Vasya tries to break in a safe. He knows that a code consists of n numbers, and every number is a 0 or a 1. Vasya has made m attempts to enter the code. After each attempt the system told him in how many position stand the right numbers. It is not said in which positions the wrong numbers stand. Vasya has been so unlucky that he hasn’t entered the code where would be more than 5 correct numbers. Now Vasya is completely bewildered: he thinks there’s a mistake in the system and it is self-contradictory. Help Vasya — calculate how many possible code variants are left that do not contradict the previous system responses.

The first input line contains two integers n and m (6 ≤ n ≤ 35, 1 ≤ m ≤ 10) which represent the number of numbers in the code and the number of attempts made by Vasya. Then follow m lines, each containing space-separated si and ci which correspondingly indicate Vasya’s attempt (a line containing n numbers which are 0 or 1) and the system’s response (an integer from 0 to 5 inclusively).

Print the single number which indicates how many possible code variants that do not contradict the m system responses are left.

$b = 4096.times.to_a.map{|i| i.to_s(2).count('1')}

def bits(x)
	$b[x & 4095] + $b[(x >> 12) & 4095] + $b[x >> 24]
end

n, m = gets.split.map(&:to_i)
a = []
m.times do |t|
	s, c = gets.split
	s = s.to_i(2)
	c = c.to_i
	if t.zero? then
		[*0..n-1].combination(c).each do |i|
			a << s
			i.each{|j| a[-1] ^= 1 << j}
		end
	else
		a.reject!{|i| bits(i ^ s) != c}
	end
end
p a.size

__END__
: || 0

n, m = gets.split.map(&:to_i)
a = []
m.times do |t|
	s, c = gets.split
	s = s.to_i(2)
	c = c.to_i
	if t.zero? then
		a = [*0..n-1].combination(n - c).to_a.map{|i| i.map{|j| 1 << j}.inject{|x, y| x ^ y} || 0}
	else
		a.reject!{|i| (i ^ s).to_s(2).count('1') != n - c}
	end
end
p a.size

__END__
: || 0

n, m = gets.split.map(&:to_i)
a = []
m.times do |t|
	s, c = gets.split
	s = s.to_i(2)
	c = c.to_i
	if t.zero? then
		a = [*0..n-1].combination(c).to_a.map{|i| i.map{|j| 1 << j}.inject{|i, j| i ^ j} || 0}
	else
		a.reject!{|i| (i ^ s).to_s(2).count('1') != c}
	end
end
p a.size

n, m = gets.split.map(&:to_i)
a = []
m.times do |t|
	s, c = gets.split
	s = s.to_i(2)
	c = c.to_i
	if t.zero? then
		a = [*0..n-1].combination(c).to_a.map{|i| i.map{|j| 1 << j}.inject{|x, y| x ^ y} || 0}
	else
		a.reject!{|i| (i ^ s).to_s(2).count('1') != c}
	end
end
p a.size

__END__
: || 0

n, m = gets.split.map(&:to_i)
a = []
m.times do |t|
	s, c = gets.split
	s = s.to_i(2)
	c = c.to_i
	if t.zero? then
		a = [*0..n-1].combination(c).to_a.map{|i| i.map{|j| 1 << j}.inject{|i, j| i ^ j}}
	else
		a.reject!{|i| (i ^ s).to_s(2).count('1') != c}
	end
end
p a.size


Vasya’s elder brother Petya loves playing computer games. In one of his favourite computer games Petya reached the final level where a fight with the boss take place.While playing the game Petya found spell scrolls and now he is about to use them. Let’s describe the way fighting goes on this level:1) The boss has two parameters: max — the initial amount of health and reg — regeneration rate per second.2) Every scroll also has two parameters: powi — spell power measured in percents — the maximal amount of health counted off the initial one, which allows to use the scroll (i.e. if the boss has more than powi percent of health the scroll cannot be used); and dmgi the damage per second inflicted upon the boss if the scroll is used. As soon as a scroll is used it disappears and another spell is cast upon the boss that inflicts dmgi of damage per second upon him until the end of the game.During the battle the actions per second are performed in the following order: first the boss gets the damage from all the spells cast upon him, then he regenerates reg of health (at the same time he can’t have more than max of health), then the player may use another scroll (no more than one per second).The boss is considered to be defeated if at the end of a second he has nonpositive ( ≤ 0) amount of health.Help Petya to determine whether he can win with the set of scrolls available to him and if he can, determine the minimal number of seconds he needs to do it.

The first line contains three integers N, max and reg (1 ≤ N, max, reg ≤ 1000) –– the amount of scrolls and the parameters of the boss. The next N lines contain two integers powi and dmgi each — the parameters of the i-th scroll (0 ≤ powi ≤ 100, 1 ≤ dmgi ≤ 2000).

In case Petya can’t complete this level, output in the single line NO. Otherwise, output on the first line YES. On the second line output the minimal time after which the boss can be defeated and the number of used scrolls. In the next lines for each used scroll output space-separated number of seconds passed from the start of the battle to the moment the scroll was used and the number of the scroll. Scrolls are numbered starting from 1 in the input order. The first scroll is considered to be available to be used after 0 seconds. Output scrolls in the order they were used. It is not allowed to use scrolls after the boss is defeated.

class Spell
	def initialize(idx, power, dmg)
		@idx = idx
		@power = power
		@dmg = dmg
		@used = false
	end
	attr_accessor :idx, :power, :dmg, :used
end

n,mx,reg = gets.chomp.split(/ /).map!{|x|x.to_i}
ra = Array.new(n)
ret = true
sa = Array.new
for i in 0..n-1
	a = gets.chomp.split(/ /).map!{|x|x.to_i}
	ra[i] = Spell.new( i+1, a[0], a[1] )
end

ra.sort!{|a,b| b.dmg <=> a.dmg }

mxw = mx
dmgpermin = 0
mtime = 0

while mxw > 0
	prevmxw = mxw
	notfound = true
	for i in 0..n-1
		next if ra[i].used
		next if ra[i].power*mx < mxw*100
		dmgpermin += ra[i].dmg
		ra[i].used = true
		sa.push( mtime.to_s + " " + ra[i].idx.to_s )
		notfound = false
		break
	end
	mxw -= dmgpermin
	mxw += reg
	mxw = mx if mxw > mx
	mtime += 1

	if notfound && prevmxw <= mxw
		ret = false
		break
	end
end

ret = false if mxw > 0

if ret
	puts "YES"
	puts mtime.to_s + " " + sa.length.to_s
	sa.each{|x| puts x }
else
	puts "NO"
end

class Spell
	def initialize(idx, power, dmg)
		@idx = idx
		@power = power
		@dmg = dmg
		@used = false
	end
	attr_accessor :idx, :power, :dmg, :used
end

n,mx,reg = gets.chomp.split(/ /).map!{|x|x.to_i}
ra = Array.new(n)
ret = true
sa = Array.new
for i in 0..n-1
	a = gets.chomp.split(/ /).map!{|x|x.to_i}
	ra[i] = Spell.new( i+1, a[0], a[1] )
end

ra.sort!{|a,b| b.dmg <=> a.dmg }

mxw = mx
dmgpermin = 0
mtime = 0

while mxw > 0
	prevmxw = mxw
	notfound = true
	for i in 0..n-1
		next if ra[i].used
		next if ra[i].power*mx < mxw*100
		dmgpermin += ra[i].dmg
		ra[i].used = true
		sa.push( mtime.to_s + " " + ra[i].idx.to_s )
		notfound = false
		break
	end
	mxw -= dmgpermin
	mxw += reg
	mxw = mx if mxw > mx

	break if mxw < 0

	mtime += 1

	if notfound && prevmxw <= mxw
		ret = false
		break
	end
end

ret = false if mxw > 0

if ret
	puts "YES"
	puts mtime.to_s + " " + sa.length.to_s
	sa.each{|x| puts x }
else
	puts "NO"
end

class Spell
	def initialize(idx, power, dmg)
		@idx = idx
		@power = power
		@dmg = dmg
		@used = false
	end
	attr_accessor :idx, :power, :dmg, :used
end

n,mx,reg = gets.chomp.split(/ /).map!{|x|x.to_i}
ra = Array.new(n)
ret = true
sa = Array.new
for i in 0..n-1
	a = gets.chomp.split(/ /).map!{|x|x.to_i}
	ra[i] = Spell.new( i+1, a[0], a[1] )
end

ra.sort!{|a,b| b.dmg <=> a.dmg }

mxw = mx
dmgpermin = 0
mtime = 0

while true
	prevmxw = mxw
	for i in 0..n-1
		next if ra[i].used
		next if ra[i].power*mx < mxw*100
		dmgpermin += ra[i].dmg
		ra[i].used = true
		sa.push( mtime.to_s + " " + ra[i].idx.to_s )
	end
	mxw -= dmgpermin
	mxw += reg
	mxw = mx if mxw > mx

	break if mxw < 0

	mtime += 1

	if prevmxw <= mxw
		ret = false
		break
	end
end

ret = false if mxw > 0

if ret
	puts "YES"
	puts mtime.to_s + " " + sa.length.to_s
	sa.each{|x| puts x }
else
	puts "NO"
end

class Spell
	def initialize(idx, power, dmg)
		@idx = idx
		@power = power
		@dmg = dmg
		@used = false
	end
	attr_accessor :idx, :power, :dmg, :used
end

n,mx,reg = gets.chomp.split(/ /).map!{|x|x.to_i}
ra = Array.new(n)
ret = true
sa = Array.new
for i in 0..n-1
	a = gets.chomp.split(/ /).map!{|x|x.to_i}
	ra[i] = Spell.new( i+1, a[0], a[1] )
end

ra.sort!{|a,b| b.dmg <=> a.dmg }

mxw = mx
dmgpermin = 0
mtime = 0

while true
	prevmxw = mxw
	notfound = true
	for i in 0..n-1
		next if ra[i].used
		next if ra[i].power*mx < mxw*100
		dmgpermin += ra[i].dmg
		ra[i].used = true
		sa.push( mtime.to_s + " " + ra[i].idx.to_s )
		notfound = false
	end
	mxw -= dmgpermin
	mxw += reg
	mxw = mx if mxw > mx

	break if mxw < 0

	mtime += 1
	if notfound && prevmxw <= mxw
		ret = false
		break
	end
end

ret = false if mxw > 0

if ret
	puts "YES"
	puts mtime.to_s + " " + sa.length.to_s
	sa.each{|x| puts x }
else
	puts "NO"
end

class Spell
	def initialize(idx, power, dmg)
		@idx = idx
		@power = power
		@dmg = dmg
		@used = false
	end
	attr_accessor :idx, :power, :dmg, :used
end

n,mx,reg = gets.chomp.split(/ /).map!{|x|x.to_i}
ra = Array.new(n)
ret = true
sa = Array.new
for i in 0..n-1
	a = gets.chomp.split(/ /).map!{|x|x.to_i}
	ra[i] = Spell.new( i+1, a[0], a[1] )
end

ra.sort!{|a,b| b.dmg <=> a.dmg }

mxw = mx
dmgpermin = 0
mtime = 0

while true
	prevmxw = mxw
	for i in 0..n-1
		next if ra[i].used
		next if ra[i].power < mxw
		dmgpermin += ra[i].dmg
		ra[i].used = true
		sa.push( mtime.to_s + " " + ra[i].idx.to_s )
	end
	mxw -= dmgpermin
	mxw += reg
	mxw = mx if mxw > mx

	break if mxw < 0

	mtime += 1

	if prevmxw <= mxw
		ret = false
		break
	end
end

ret = false if mxw > 0

if ret
	puts "YES"
	puts mtime.to_s + " " + sa.length.to_s
	sa.each{|x| puts x }
else
	puts "NO"
end

class Spell
	def initialize(idx, power, dmg)
		@idx = idx
		@power = power
		@dmg = dmg
		@used = false
	end
	attr_accessor :idx, :power, :dmg, :used
end

n,mx,reg = gets.chomp.split(/ /).map!{|x|x.to_i}
ra = Array.new(n)
ret = true
sa = Array.new
for i in 0..n-1
	a = gets.chomp.split(/ /).map!{|x|x.to_i}
	ra[i] = Spell.new( i+1, a[0], a[1] )
end

ra.sort!{|a,b| b.dmg <=> a.dmg }

mxw = mx
dmgpermin = 0
mtime = 0

while true
	prevmxw = mxw
	notfound = true
	for i in 0..n-1
		next if ra[i].used
		next if ra[i].power*mx < mxw*100
		dmgpermin += ra[i].dmg
		ra[i].used = true
		sa.push( mtime.to_s + " " + ra[i].idx.to_s )
		notfound = false
		break
	end
	mxw -= dmgpermin
	mxw += reg
	mxw = mx if mxw > mx

	break if mxw < 0

	mtime += 1
if mtime > 10000
	ret = false
	break
end
#	if notfound && prevmxw <= mxw
#		ret = false
#		break
#	end
end

ret = false if mxw > 0

if ret
	puts "YES"
	puts mtime.to_s + " " + sa.length.to_s
	sa.each{|x| puts x }
else
	puts "NO"
end

class Spell
	def initialize(idx, power, dmg)
		@idx = idx
		@power = power
		@dmg = dmg
		@used = false
	end
	attr_accessor :idx, :power, :dmg, :used
end

n,mx,reg = gets.chomp.split(/ /).map!{|x|x.to_i}
ra = Array.new(n)
ret = true
sa = Array.new
for i in 0..n-1
	a = gets.chomp.split(/ /).map!{|x|x.to_i}
	ra[i] = Spell.new( i+1, a[0], a[1] )
end

ra.sort!{|a,b| b.dmg <=> a.dmg }

mxw = mx
dmgpermin = 0
mtime = 0

while true
	prevmxw = mxw
	notfound = true
	for i in 0..n-1
		next if ra[i].used
		next if ra[i].power*mx < mxw*100
		dmgpermin += ra[i].dmg
		ra[i].used = true
		sa.push( mtime.to_s + " " + ra[i].idx.to_s )
		notfound = false
		break
	end
	mxw -= dmgpermin
	mxw += reg
	mxw = mx if mxw > mx

	break if mxw < 0

	mtime += 1
	if notfound && prevmxw <= mxw
		ret = false
		break
	end
end

ret = false if mxw > 0

if ret
	puts "YES"
	puts mtime.to_s + " " + sa.length.to_s
	sa.each{|x| puts x }
else
	puts "NO"
end


This is an interactive problem.Vasya and Petya are going to play the following game: Petya has some positive integer number $$$a$$$. After that Vasya should guess this number using the following questions. He can say a pair of non-negative integer numbers $$$(x, y)$$$. Petya will answer him:   "x", if $$$(x \bmod a) \geq (y \bmod a)$$$.  "y", if $$$(x \bmod a) < (y \bmod a)$$$. We define $$$(x \bmod a)$$$ as a remainder of division $$$x$$$ by $$$a$$$.Vasya should guess the number $$$a$$$ using no more, than 60 questions.It's guaranteed that Petya has a number, that satisfies the inequality $$$1 \leq a \leq 10^9$$$.Help Vasya playing this game and write a program, that will guess the number $$$a$$$.

NoteIn the first test, you should play $$$3$$$ games with Petya's numbers $$$1$$$, $$$2$$$ and $$$3$$$.In the first game, Petya will answer "x" (without quotes) to any question, because $$$(x \bmod 1) = 0$$$ for any integer $$$x$$$. In the second game, if you will ask pair $$$(0, 0)$$$, the answer will be "x" (without quotes), because $$$(0 \bmod 2) \geq (0 \bmod 2)$$$. But if you will ask pair $$$(2, 5)$$$, the answer will be "y" (without quotes), because $$$(2 \bmod 2) < (5 \bmod 2)$$$, because $$$(2 \bmod 2) = 0$$$ and $$$(5 \bmod 2) = 1$$$.

require 'prime'

p = Prime.each(10**5).to_a

loop do
    s = gets.chomp
    break if s == "end"
    min = 0
    max = 10**9
    while max-min > 1
        mid = (min+max)/2
        puts "? #{mid} #{max}"
        STDOUT.flush
        r = gets.chomp
        if r == "x"
            min = mid
        else
            max = mid
        end
    end
    m = max
    ret = 1
    p.each do |i|
        a = 0
        while m%i == 0
            a += 1
            puts "? #{max} #{max/(i**a)}"
            STDOUT.flush
            r = gets.chomp
            if r == "y"
                ret *= i
            end
            m /= i
        end
    end
    puts "? #{max} #{max/m}"
    STDOUT.flush
    r = gets.chomp
    if r == "y"
        ret *= m
    end

    puts "! #{ret}"
    STDOUT.flush
end

DBG = !true
def outp(str)
  puts str
  STDOUT.flush
end

def lt(x,y)
  hashkey = x.to_s + "." + y.to_s
  if $h.has_key?(hashkey)
    return $h[hashkey]
  end
  outp("? #{x} #{y}")
  s = gets.chomp
  exit(0) if s == 'mistake'
  $h[hashkey] = (s=='y')
  return (s=='y')
end

$h = {}
R = (DBG ? 10 : 1000000000)
MONO = 1
SPLIT = 2
S1N = 3
while true
  $h.clear()
  inp = gets.chomp
  exit(0) if inp == "end" || inp == "mistake"
  next if inp != 'start'
  st = MONO
  s = R
  b = t = -1
  while true
    puts "st #{st} s #{s} b #{b} t #{t}" if DBG
    if st == MONO
      if s == 2
        st = S1N
        b = t = 2
        next
      end
      p = s - 2*(s/3)
      q = s - s/3
      if lt(p, q)
        st = SPLIT
        t = s
        s = p
        b = q + 1
      else
        s = q
      end

    elsif st == SPLIT
      if s == 1
        st = S1N
        next
      end
      p = s - s/2
      if lt(p,s)
        s = p
      else
        st = MONO
        b = t = -1
      end
    else # st = S1N
      if b < t
        p = (b+t)/2
        if lt(p,t)
          t = p
        else
          b = (b==t-1 ? t : p+1)
        end
      else  # b == t
        if lt(t,1)
          outp("! #{t}")
        else
          outp("! 1")
        end
        break
      end
    end
  end
end

@local = false
@answer = 1
@gamecnt = 100

def continue_game
    if @local
        return false if @gamecnt <= 0
        @gamecnt -= 1
        @querycnt = 0
        return true
    else
        line = gets.chomp
        exit if line == "mistake"
        return line == "start"
    end
end

def query_game(x,y)
    if @local
        @querycnt += 1
        return x%@answer >= y%@answer
    else
        STDOUT.puts "? #{x} #{y}"
        STDOUT.flush
        return gets[0] == "x"
    end
end

def answer_game(a)
    if @local
        abort "#{@answer} != #{a}" if @answer != a
        puts "AC:#{@querycnt}"
        @answer = rand(1..(1e9.to_i))
    else
        STDOUT.puts "! #{a}"
        STDOUT.flush
    end
end

#

while continue_game

    x = 1
    y = 0

    while x <= 2e9.to_i && query_game(x, y)
        x, y = x*2, x
    end
    if x > 2e9
        answer_game(1)
        next
    end
    while x-y > 1
        m = (x+y)/2
        if query_game(m, y)
            y = m
        else
            x = m
        end
    end
    answer_game(x)
end

loop do
    s = gets.chomp
    break if s == "end"
    min = 0
    max = 10**9
    while max-min > 1
        mid = (min+max)/2
        puts "? #{mid} #{max}"
        STDOUT.flush
        r = gets.chomp
        if r == "x"
            min = mid
        else
            max = mid
        end
    end
    m = max
    for i in 2..31623
        while m%i == 0
            puts "? #{max} #{max/i}"
            STDOUT.flush
            r = gets.chomp
            if r == "y"
                break
            else
                max /= i
            end
            m /= i
        end
        while m%i == 0
            m /= i
        end
    end
    puts "! #{max}"
    STDOUT.flush
end

require 'prime'

p = Prime.each(10**5).to_a

loop do
    s = gets.chomp
    break if s == "end"
    min = 0
    max = 10**9
    while max-min > 1
        mid = (min+max)/2
        puts "? #{mid} #{max}"
        STDOUT.flush
        r = gets.chomp
        if r == "x"
            min = mid
        else
            max = mid
        end
    end
    m = max
    ret = 1
    p.each do |i|
        a = 0
        while m%i == 0
            a += 1
            puts "? #{max} #{max/i}"
            STDOUT.flush
            r = gets.chomp
            if r == "y"
                ret *= i
            end
            m /= i
        end
    end
    puts "? #{max} #{max/m}"
    STDOUT.flush
    r = gets.chomp
    if r == "y"
        ret *= m
    end

    puts "! #{max}"
    STDOUT.flush
end

require 'prime'

p = Prime.each(10**5).to_a

loop do
    s = gets.chomp
    break if s == "end"
    min = 0
    max = 10**9
    while max-min > 1
        mid = (min+max)/2
        puts "? #{mid} #{max}"
        STDOUT.flush
        r = gets.chomp
        if r == "x"
            min = mid
        else
            max = mid
        end
    end
    m = max
    ret = 1
    p.each do |i|
        a = 0
        while m%i == 0
            a += 1
            puts "? #{max} #{max/i}"
            STDOUT.flush
            r = gets.chomp
            if r == "y"
                ret *= i
            end
            m /= i
        end
    end
    puts "? #{max} #{max/m}"
    STDOUT.flush
    r = gets.chomp
    if r == "y"
        ret *= m
    end

    puts "! #{ret}"
    STDOUT.flush
end

def ret(a,x,y)
    if x%a >= y%a
        return "x"
    else
        return "y"
    end
end

loop do
    s = gets.chomp
    break if s == "end"
    min = 0
    max = 10**9
    #ans = rand(1..10**9)
    #p ans
    while max-min > 1
        mid = (min+max)/2
        puts "? #{mid} #{max}"
        STDOUT.flush
        r = gets.chomp
        #r = ret(ans,mid,max)
        if r == "x"
            min = mid
        else
            max = mid
        end
    end
    for i in 2..31623
        while max%i == 0
            puts "? #{max} #{max/i}"
            STDOUT.flush
            r = gets.chomp
            #r = ret(ans,max,max/i)
            if r == "y"
                break
            else
                max /= i
            end
        end
    end
    puts "! #{max}"
    STDOUT.flush
end

require 'prime'

loop do
    s = gets.chomp
    break if s == "end"
    min = 0
    max = 10**9
    while max-min > 1
        mid = (min+max)/2
        puts "? #{mid} #{max}"
        STDOUT.flush
        r = gets.chomp
        if r == "x"
            min = mid
        else
            max = mid
        end
    end
    m = max
    Prime.each(10**5) do |i|
        break if i > m || m%i != 0
        while m%i == 0
            puts "? #{max} #{max/i}"
            STDOUT.flush
            r = gets.chomp
            if r == "x"
                max /= i
            else
                break
            end
            m /= i
        end
        while m%i == 0
            m /= i
        end
        puts "? #{max} #{i}"
        STDOUT.flush
        r = gets.chomp
        if r == "x"
            max = i
            m = i
        end
    end
    puts "! #{max}"
    STDOUT.flush
end

def ret(a,x,y)
    if x%a >= y%a
        return "x"
    else
        return "y"
    end
end

loop do
    s = gets.chomp
    break if s == "end"
    min = 0
    max = 10**9
    #ans = rand(1..10**9)
    #p ans
    while max-min > 1
        mid = (min+max)/2
        puts "? #{mid} #{min}"
        STDOUT.flush
        r = gets.chomp
        #r = ret(ans,mid,max)
        if r == "x"
            min = mid
        else
            max = mid
        end
    end
    for i in 2..31623
        while max%i == 0
            puts "? #{max} #{max/i}"
            STDOUT.flush
            r = gets.chomp
            #r = ret(ans,max,max/i)
            if r == "y"
                break
            else
                max /= i
            end
        end
    end
    puts "! #{max}"
    STDOUT.flush
end

DBG = !true
def outp(str)
  puts str
  STDOUT.flush
end

def lt(x,y)
  outp("? #{x} #{y}")
  s = gets.chomp
  exit(0) if s == 'mistake'
  return (s=='y')
end

R = (DBG ? 10 : 1000000000)
MONO = 1
SPLIT = 2
S1N = 3
while true
  inp = gets.chomp
  exit(0) if inp == "end" || inp == "mistake"
  next if inp != 'start'
  st = MONO
  s = R
  b = t = -1
  while true
    puts "st #{st} s #{s} b #{b} t #{t}" if DBG
    if st == MONO
      if s == 2
        st = S1N
        b = t = 2
        next
      end
      p = s - 2*(s/3)
      q = s - s/3
      if lt(p, q)
        st = SPLIT
        t = s
        s = p
        b = q
      else
        s = q
      end

    elsif st == SPLIT
      if s == 1
        st = S1N
        next
      end
      p = s - s/2
      if lt(p,s)
        s = p
      else
        st = MONO
        b = t = -1
      end
    else # st = S1N
      if b < t
        p = (b+t)/2
        if lt(p,t)
          t = p
        else
          b = (b==t-1 ? t : p)
        end
      else  # b == t
        if lt(t,1)
          outp("! #{t}")
        else
          outp("! 1")
        end
        break
      end
    end
  end
end

DBG = !true
def outp(str)
  puts str
  STDOUT.flush
end

def lt(x,y)
  hashkey = x.to_s + "." + y.to_s
  if $h.has_key?(hashkey)
    return $h[hashkey]
  end
  outp("? #{x} #{y}")
  s = gets.chomp
  exit(0) if s == 'mistake'
  $h[hashkey] = (s=='y')
  return (s=='y')
end

$h = {}
R = (DBG ? 10 : 1000000000)
MONO = 1
SPLIT = 2
S1N = 3
while true
  $h.clear()
  inp = gets.chomp
  exit(0) if inp == "end" || inp == "mistake"
  next if inp != 'start'
  st = MONO
  s = R
  b = t = -1
  while true
    puts "st #{st} s #{s} b #{b} t #{t}" if DBG
    if st == MONO
      if s == 2
        st = S1N
        b = t = 2
        next
      end
      p = s - 2*(s/3)
      q = s - s/3
      if lt(p, q)
        st = SPLIT
        t = s
        s = p
        b = q + 1
      else
        s = q
      end

    elsif st == SPLIT
      if s == 1
        st = S1N
        next
      end
      p = s - s/2
      if lt(p,s)
        s = p
      else
        st = MONO
        b = t = -1
      end
    else # st = S1N
      if b < t
        p = (b+t)/2
        if lt(p,t)
          t = p
        else
          b = (b==t-1 ? t : p)
        end
      else  # b == t
        if lt(t,1)
          outp("! #{t}")
        else
          outp("! 1")
        end
        break
      end
    end
  end
end

DBG = !true
def outp(str)
  puts str
  STDOUT.flush
end

def lt(x,y)
  hashkey = x.to_s + "." + y.to_s
  if $h.has_key?(hashkey)
    return $h[hashkey]
  end
  outp("? #{x} #{y}")
  s = gets.chomp
  exit(0) if s == 'mistake'
  $h[hashkey] = (s=='y')
  return (s=='y')
end

$h = {}
R = (DBG ? 10 : 1000000000)
MONO = 1
SPLIT = 2
S1N = 3
while true
  $h.clear()
  inp = gets.chomp
  exit(0) if inp == "end" || inp == "mistake"
  next if inp != 'start'
  st = MONO
  s = R
  b = t = -1
  while true
    puts "st #{st} s #{s} b #{b} t #{t}" if DBG
    if st == MONO
      if s == 2
        st = S1N
        b = t = 2
        next
      end
      p = s - 2*(s/3)
      q = s - s/3
      if lt(p, q)
        st = SPLIT
        t = s
        s = p
        b = q
      else
        s = q
      end

    elsif st == SPLIT
      if s == 1
        st = S1N
        next
      end
      p = s - s/2
      if lt(p,s)
        s = p
      else
        st = MONO
        b = t = -1
      end
    else # st = S1N
      if b < t
        p = (b+t)/2
        if lt(p,t)
          t = p
        else
          b = (b==t-1 ? t : p)
        end
      else  # b == t
        if lt(t,1)
          outp("! #{t}")
        else
          outp("! 1")
        end
        break
      end
    end
  end
end

DBG = true
def outp(str)
  puts str
  STDOUT.flush
end

def lt(x,y)
  outp("? #{x} #{y}")
  s = gets.chomp
  exit(0) if s == 'mistake'
  return (s=='y')
end

R = (DBG ? 10 : 1000000000)
MONO = 1
SPLIT = 2
S1N = 3
while true
  inp = gets.chomp
  exit(0) if inp == "end" || inp == "mistake"
  next if inp != 'start'
  st = MONO
  s = R
  b = t = -1
  while true
    puts "st #{st} s #{s} b #{b} t #{t}" if DBG
    if st == MONO
      if s == 2
        st = S1N
        b = t = 2
        next
      end
      p = s - 2*(s/3)
      q = s - s/3
      if lt(p, q)
        st = SPLIT
        t = s
        s = p
        b = q
      else
        s = q
      end

    elsif st == SPLIT
      if s == 1
        st = S1N
        next
      end
      p = s - s/2
      if lt(p,s)
        s = p
      else
        st = MONO
        b = t = -1
      end
    else # st = S1N
      if b < t
        p = (b+t)/2
        if lt(p,t)
          t = p
        else
          b = (b==t-1 ? t : p)
        end
      else  # b == t
        if lt(t,1)
          outp("! #{t}")
        else
          outp("! 1")
        end
        break
      end
    end
  end
end

@local = false
@answer = 1
@trycnt = 29

def continue_game
    if @local
        return false if @trycnt <= 0
        @trycnt -= 1
        return true
    else
        line = gets.chomp
        exit if line == "mistake"
        return line == "start"
    end
end

def query_game(x,y)
    if @local
        return x%@answer >= y%@answer
    else
        STDOUT.puts "? #{x} #{y}"
        STDOUT.flush
        return gets[0] == "x"
    end
end

def answer_game(a)
    if @local
        abort if @answer != a
        puts "AC"
        @answer = rand(1..100000)
    else
        STDOUT.puts "! #{a}"
        STDOUT.flush
    end
end

#

while continue_game

    if query_game(0, 1)
        answer_game(1)
        next
    end
    x = 1
    y = 0

    while query_game(x, y)
        x, y = x*2, x
    end
    while x-y > 1
        m = (x+y)/2
        if query_game(m, y)
            y = m
        else
            x = m
        end
    end
    answer_game(x)
end


The only difference between easy and hard versions is the constraints.Polycarp has to write a coursework. The coursework consists of $$$m$$$ pages.Polycarp also has $$$n$$$ cups of coffee. The coffee in the $$$i$$$-th cup Polycarp has $$$a_i$$$ caffeine in it. Polycarp can drink some cups of coffee (each one no more than once). He can drink cups in any order. Polycarp drinks each cup instantly and completely (i.e. he cannot split any cup into several days).Surely, courseworks are not being written in a single day (in a perfect world of Berland, at least).Let's consider some day of Polycarp's work. Consider Polycarp drinks $$$k$$$ cups of coffee during this day and caffeine dosages of cups Polycarp drink during this day are $$$a_{i_1}, a_{i_2}, \dots, a_{i_k}$$$. Then the first cup he drinks gives him energy to write $$$a_{i_1}$$$ pages of coursework, the second cup gives him energy to write $$$max(0, a_{i_2} - 1)$$$ pages, the third cup gives him energy to write $$$max(0, a_{i_3} - 2)$$$ pages, ..., the $$$k$$$-th cup gives him energy to write $$$max(0, a_{i_k} - k + 1)$$$ pages.If Polycarp doesn't drink coffee during some day, he cannot write coursework at all that day.Polycarp has to finish his coursework as soon as possible (spend the minimum number of days to do it). Your task is to find out this number of days or say that it is impossible.

The first line of the input contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n \le 2 \cdot 10^5$$$, $$$1 \le m \le 10^9$$$) — the number of cups of coffee and the number of pages in the coursework. The second line of the input contains $$$n$$$ integers $$$a_1, a_2, \dots, a_n$$$ ($$$1 \le a_i \le 10^9$$$), where $$$a_i$$$ is the caffeine dosage of coffee in the $$$i$$$-th cup.

If it is impossible to write the coursework, print -1. Otherwise print the minimum number of days Polycarp needs to do it.

NoteIn the first example Polycarp can drink fourth cup during first day (and write $$$1$$$ page), first and second cups during second day (and write $$$2 + (3 - 1) = 4$$$ pages), fifth cup during the third day (and write $$$2$$$ pages) and third cup during the fourth day (and write $$$1$$$ page) so the answer is $$$4$$$. It is obvious that there is no way to write the coursework in three or less days.In the second example Polycarp can drink third, fourth and second cups during first day (and write $$$4 + (2 - 1) + (3 - 2) = 6$$$ pages) and sixth cup during second day (and write $$$4$$$ pages) so the answer is $$$2$$$. It is obvious that Polycarp cannot write the whole coursework in one day in this test.In the third example Polycarp can drink all cups of coffee during first day and write $$$5 + (5 - 1) + (5 - 2) + (5 - 3) + (5 - 4) = 15$$$ pages of coursework.In the fourth example Polycarp cannot drink all cups during first day and should drink one of them during the second day. So during first day he will write $$$5 + (5 - 1) + (5 - 2) + (5 - 3) = 14$$$ pages of coursework and during second day he will write $$$5$$$ pages of coursework. This is enough to complete it.In the fifth example Polycarp cannot write the whole coursework at all, even if he will drink one cup of coffee during each day, so the answer is -1.

n, m = gets.split.map(&:to_i)
a = gets.split.map(&:to_i).sort.reverse

puts (1..n).bsearch { |day|
		sum = a[0, day].sum
		minus, cnt = 1, 0
		(day...n).each do |i|
			sum += [0, a[i] - minus].max
			cnt += 1
			if cnt == day
				minus += 1
				cnt = 0
			end
		end
		sum >= m
     } || -1


You've got an array a, consisting of n integers: a1, a2, ..., an. Your task is to find a minimal by inclusion segment [l, r] (1 ≤ l ≤ r ≤ n) such, that among numbers al,  al + 1,  ...,  ar there are exactly k distinct numbers.Segment [l, r] (1 ≤ l ≤ r ≤ n; l, r are integers) of length m = r - l + 1, satisfying the given property, is called minimal by inclusion, if there is no segment [x, y] satisfying the property and less then m in length, such that 1 ≤ l ≤ x ≤ y ≤ r ≤ n. Note that the segment [l, r] doesn't have to be minimal in length among all segments, satisfying the given property.

The first line contains two space-separated integers: n and k (1 ≤ n, k ≤ 105). The second line contains n space-separated integers a1, a2, ..., an — elements of the array a (1 ≤ ai ≤ 105).

Print a space-separated pair of integers l and r (1 ≤ l ≤ r ≤ n) such, that the segment [l, r] is the answer to the problem. If the sought segment does not exist, print "-1 -1" without the quotes. If there are multiple correct answers, print any of them.

NoteIn the first sample among numbers a1 and a2 there are exactly two distinct numbers.In the second sample segment [2, 5] is a minimal by inclusion segment with three distinct numbers, but it is not minimal in length among such segments.In the third sample there is no segment with four distinct numbers.

def execute(n, k, arr)
  return [1, 1] if k == 1
  return [-1, -1] if k > n

  @lelf, @right = 0
  @arr_count = [0] * (10**5 + 1)
  @count = 0

  for j in 0..n-1
    @arr_count[arr[j]] += 1

    if @arr_count[arr[j]] == 1
      @count += 1
      @right = j
    end
    # puts "puts arr[#{j}]: #{arr[j]}, number count: #{@arr_count[arr[j]]},  @count: #{@count}, }"

    if @count == k
      break
    end

  end

  return [-1, -1] if @count < k

  while @count == k
    @arr_count[arr[@lelf]] -= 1
    if @arr_count[arr[@lelf]] == 0
      break
    end
    @lelf += 1
  end

  return [@lelf + 1, @right + 1]
end

n, k = gets.chomp.split(' ').map(&:to_i)
arr = gets.chomp.split(' ').map(&:to_i)
result = execute(n, k, arr)
puts result.join(' ')

#!/usr/bin/ruby

n, k = STDIN.readline.split.collect {|s| s.to_i }
arr = STDIN.readline.split.collect {|s| s.to_i }
if arr.uniq.length < k
	puts '-1 -1'
	exit
end
if k == 1
	puts '1 1'
	exit
end
count = 1
unique_hash = { arr[0] => true }
right = 0
while count < k
	right += 1
	x = arr[right]
	if not unique_hash.include? x
		unique_hash[x] = true
		count += 1
	end
end
count = 1
left = right
unique_hash = { arr[right] => true }
while count < k
	left -= 1
	x = arr[left]
	if not unique_hash.include? x
		unique_hash[x] = true
		count += 1
	end
end
puts '%d %d' % [left+1, right+1]

n, k = gets.rstrip.split.map(&:to_i)
arr = gets.rstrip.split.map(&:to_i)

tmp = []
l = r = 0

count = 0

while r < n do
  tmp[arr[r]] ? tmp[arr[r]] += 1 : tmp[arr[r]] = 1
  count += 1 if tmp[arr[r]] == 1
  if count == k
    while l <= r do
      tmp[arr[l]] -= 1
      if tmp[arr[l]] == 0
        puts "#{l + 1} #{r + 1}"
        exit
      end
      l += 1
    end
  end
  r += 1
end

puts "-1 -1"

require 'set'
buf = gets.split(' ')
n = buf[0].to_i
k = buf[1].to_i
st = Set.new
buf = gets.split(' ')
0.upto(n - 1) { |ii|
    i = buf[ii]
    st.add(i)
    if st.size == k
        st.clear
        ii.downto(0) { |jj|
            j = buf[jj]
            st.add(j)
            if st.size == k
                print jj + 1, " ", ii + 1
                exit 0
            end
        }
    end
}
print "-1 -1"

n, k = gets.chomp.split.map(&:to_i)
list = gets.chomp.split.map(&:to_i)

def aaa(list, k)
  count = Hash.new { |hash, key| hash[key] = 0 }

  for r in 0..(list.length - 1)
    count[list[r]] += 1

    if count[list[r]] == 1
      k -= 1
    end

    if k == 0
      for l in 0..r
        count[list[l]] = count[list[l]] - 1

        if count[list[l]] == 0
          return [l + 1, r + 1]
        end
      end
    end
  end

  return [-1, -1]
end

result = aaa(list, k)

print result[0], " ", result[1]

require 'set'

$incr = Proc.new {|st,x| st[x].nil? ? (st[x] = 1) : (st[x] += 1) }
$decr = Proc.new {|st,x| st[x].nil? ? 0 : (st[x] == 1 ? (st.delete x) : (st[x] -= 1) ) }
$dis  = Proc.new {|ls| st = {}; ls.each {|x| $incr.(st,x) } ; st }

def good(ls,m,k)

  l = ls.length - m - 1
  st = $dis.(ls.take(m))
  cnt = st.size
  if cnt >= k
    return [true,0,ls]
  else
    (0..l).each do |i|
      $incr.(st,ls[m+i])
      $decr.(st,ls[i])
      if st.size >= k
        ar = Array.new(m)
        i += 1
        m.times do |j|
          ar[j] = ls[j+i]
        end
        return [true,i,ar]
      end
    end
  end
  return [false]
end

def doIt(n,k,ls)
  off = 0
  h = n
  l = [k - 1,0].max
  a = [false]
  while (h - l > 1)
    m = (h+l) / 2
    a = good(ls,m,k)
    if a.first
      h = m
      ls = a[2]
      off += a[1]
    else
      l = m
    end
  end
  a = good(ls,h,k)
  puts "#{a[1]+1+off} #{a[1]+h+off}"

end

xs = gets.split.map(&:to_i)
n, k = xs[0], xs[1]
ls = gets.split.map(&:to_i)

st = Set.new

ls.each {|x| st.add x}

if st.size < k then
  puts "-1 -1" #cant be done
else
  doIt(n,k,ls)
end

require 'set'

def good(ls,m,k)

  incr = Proc.new {|st,x| st[x].nil? ? (st[x] = 1) : (st[x] += 1) }
  decr = Proc.new {|st,x| st[x].nil? ? 0 : (st[x] == 1 ? (st.delete x) : (st[x] -= 1) ) }
  dis  = Proc.new {|ls| st = {}; ls.each {|x| incr.(st,x) } ; st }

  l = ls.length - m - 1
  st = dis.(ls.take(m))
  cnt = st.size
  if cnt >= k
    return [true,0,ls]
  else
    (0..l).each do |i|
      incr.(st,ls[m+i])
      decr.(st,ls[i])
      if st.size >= k
        ar = Array.new(m)
        i += 1
        m.times do |j|
          ar[j] = ls[j+i]
        end
        return [true,i,ar]
      end
    end
  end
  return [false]
end

def doIt(n,k,ls)
  off = 0
  h = n
  l = [k - 1,0].max
  a = [false]
  while (h - l > 1)
    m = (h+l) / 2
    a = good(ls,m,k)
    if a.first
      h = m
      ls = a[2]
      off += a[1]
    else
      l = m
    end
  end
  a = good(ls,h,k)
  puts "#{a[1]+1+off} #{a[1]+h+off}"

end

xs = gets.split.map(&:to_i)
n, k = xs[0], xs[1]
ls = gets.split.map(&:to_i)

st = Set.new

ls.each {|x| st.add x}

if st.size < k then
  puts "-1 -1" #cant be done
else
  doIt(n,k,ls)
end

def execute(n, k, arr)
  @count = 0
  @arr_count = [0] * n
  @arr_count[0] = 1
  @lelf, @right = 0

  for j in 1..n-1
    @i = 0

    # skip if arr[j] count before
    # next if @arr_count[arr.index(@arr_count[j])] == 0

    while @i < j do
      if arr[@i] == arr[j]
        @arr_count[j] = @arr_count[j - 1]
        break
      end
      @i += 1
    end

    # item no exist [i..j-2]
    if @i == j
      @arr_count[j] = @arr_count[j - 1] + 1
      @right = j
      @count = @arr_count[j]
    end

    # puts "j: #{j}, @count: #{@count}, #{@arr_count.join(' ')}"

    break if @arr_count[j] == k
  end

  # check @count, shifl @lelf + 1

  if @count < k
    return [-1, -1]
  else
    while @arr_count[@lelf + 1] == 1
      @lelf += 1
    end
    return [@lelf + 1, @right + 1] if @right > 0
  end

end

# puts "test case 1"
# puts execute(4, 2,  %w(1 2 2 3).map(&:to_i)).inspect
# #arr_count             1 2 0 0

# puts "test case 2"
# puts execute(8, 3, %w(1 1 2 2 3 3 4 5).map(&:to_i)).inspect
# #arr_count            1 1 2 2 3 0 0 0

# puts "test case 3"
# puts execute(7, 4, %w(4 7 7 4 7 4 7).map(&:to_i)).inspect
# #arr_count            1 2 2 2 2 2 2

n, k = gets.chomp.split(' ').map(&:to_i)
arr = gets.chomp.split(' ').map(&:to_i)
result = execute(n, k, arr)
puts result.join(' ')

#!/usr/bin/ruby

n, k = STDIN.readline.split.collect {|s| s.to_i }
arr = STDIN.readline.split.collect {|s| s.to_i }
if arr.uniq.length < k
	puts '-1 -1'
	exit
end
if k == 1
	puts '1 1'
	exit
end
start = 0
start += 1 while arr[start] == arr[start+1]
count = 1
unique_hash = { arr[start] => true }
pos = start
while count < k
	pos += 1
	x = arr[pos]
	if not unique_hash.include? x
		unique_hash[x] = true
		count += 1
	end
end
puts '%d %d' % [start+1, pos+1]

n, k = gets.rstrip.split.map(&:to_i)
arr = gets.rstrip.split.map(&:to_i)

distinct_arr = arr.uniq
tmp = []

if distinct_arr.size < k
  puts "-1 -1"
else
  k.times.each do |i|
    tmp.push(distinct_arr[i])
  end

  res = []
  max = tmp.max
  tmp.each do |v|
    if v == max
      res.push(arr.each_index.select { |i| arr[i] == v }.min)
    else
      res.push(arr.each_index.select { |i| arr[i] == v }.max)
    end
  end

  puts "#{res.first + 1} #{res.last + 1}"
end

n, k = gets.rstrip.split.map(&:to_i)
arr = gets.rstrip.split.map(&:to_i)

distinct_arr = arr.uniq
tmp = []

if distinct_arr.size < k
  puts "-1 -1"
else
  k.times.each do |i|
    tmp.push(distinct_arr[i])
  end

  last = arr.each_index.select { |i| arr[i] == tmp[-1] }.min
  first = arr.each_index.select { |i| arr[i] == tmp[0] && i < last }.max

  puts "#{first.to_i + 1} #{last.to_i + 1}"
end

n, k = gets.rstrip.split.map(&:to_i)
arr = gets.rstrip.split.map(&:to_i)

distinct_arr = arr.uniq
tmp = []

if distinct_arr.size < k
  puts "-1 -1"
else
  k.times.each do |i|
    tmp.push(distinct_arr[i])
  end

  res = []
  tmp.each do |v|
    if v == tmp[-1]
      res.push(arr.each_index.select { |i| arr[i] == v }.min)
    else
      res.push(arr.each_index.select { |i| arr[i] == v }.max)
    end
  end

  puts "#{res.first + 1} #{res.last + 1}"
end

require 'set'
buf = gets.split(' ')
n = buf[0].to_i
k = buf[1].to_i
st = Set.new
buf = gets.split(' ')
0.upto(n - 1) { |ii|
    i = buf[ii]
    st.add(i)
    if st.size == k
      print 1, " ", ii + 1
      exit 0
    end
}
print "-1 -1"

n, k = gets.chomp.split.map(&:to_i)
list = gets.chomp.split.map(&:to_i)

def aaa(list, k)
  hash = Hash.new { |hash, key| hash[key] = 0 }
  for i in 0..(list.length - 1)
    hash[list[i]] += 1
  end

  if hash.keys.count < k
    return [-1, -1]
  else
    b = []
    for i in 0..(list.length - 1)
      b << [i, list[i]]

      if list[i] != list[i + 1]
        k = k - 1
      end

      if k == 0
        break
      end
    end
    b
    c = []
    d = []
    for i in 0..(b.length - 1)
      if b[i][1] == b[0][1]
        c << i
      end
      if b[i][1] == b[-1][1]
        d << i
      end
    end
    return [c.max + 1, d.min + 1]
  end
end

result = aaa(list, k)
result.each do |i|
  print i
  print " " if i != result[-1]
end

n, k = gets.chomp.split.map(&:to_i)
list = gets.chomp.split.map(&:to_i)

def aaa(list, k)
  hash = Hash.new { |hash, key| hash[key] = 0 }
  for i in 0..(list.length - 1)
    hash[list[i]] += 1
  end

  if hash.keys.count < k
    "-1 -1"
  else
    b = []
    for i in 0..(list.length - 1)
      b << [i, list[i]]

      if list[i] != list[i + 1]
        k = k - 1
      end

      if k == 0
        break
      end
    end
    b
    c = []
    d = []
    for i in 0..(b.length - 1)
      if b[i][1] == b[0][1]
        c << i
      end
      if b[i][1] == b[-1][1]
        d << i
      end
    end
    "#{c.max + 1} #{d.min + 1}"
  end
end

p aaa(list, k)

n, k = gets.chomp.split.map(&:to_i)
list = gets.chomp.split.map(&:to_i)

def aaa(list, k)
  hash = Hash.new { |hash, key| hash[key] = 0 }
  for i in 0..(list.length - 1)
    hash[list[i]] += 1
  end

  if hash.keys.count < k
    return [-1, -1]
  else
    b = []
    for i in 0..(list.length - 1)
      b << [i, list[i]]

      if list[i] != list[i + 1]
        k = k - 1
      end

      if k == 0
        break
      end
    end
    b
    c = []
    d = []
    for i in 0..(b.length - 1)
      if b[i][1] == b[0][1]
        c << i
      end
      if b[i][1] == b[-1][1]
        d << i
      end
    end
    return [c.max + 1, d.min + 1]
  end
end

result = aaa(list, k)
result.each.with_index do |element, index|
  print element
  print " " if index != result.length - 1
end

n, k = gets.chomp.split.map(&:to_i)
list = gets.chomp.split.map(&:to_i)

def aaa(list, k)
  hash = Hash.new { |hash, key| hash[key] = 0 }
  for i in 0..(list.length - 1)
    hash[list[i]] += 1
  end

  if hash.keys.count < k
    return [-1, -1]
  else
    b = []
    for i in 0..(list.length - 1)
      b << [i, list[i]]

      if list[i] != list[i + 1]
        k = k - 1
      end

      if k == 0
        break
      end
    end
    b
    c = []
    d = []
    for i in 0..(b.length - 1)
      if b[i][1] == b[0][1]
        c << i
      end
      if b[i][1] == b[-1][1]
        d << i
      end
    end
    return [c.max, d.min]
  end
end

result = aaa(list, k)
result.each do |i|
  print i
  print " " if i != result[-1]
end

require 'set'

def good(ls,m,k)

  incr = Proc.new {|st,x| st[x].nil? ? (st[x] = 1) : (st[x] += 1) }
  decr = Proc.new {|st,x| st[x].nil? ? 0 : (st[x] == 1 ? (st.delete x) : (st[x] -= 1) ) }
  dis  = Proc.new {|ls| st = {}; ls.each {|x| incr.(st,x) } ; st }

  l = ls.length - m - 1
  tk  = ls.take(m)
  st = dis.(tk)
  cnt = st.size
  if cnt >= k
    return [true,0,tk]
  else
    (0..l).each do |i|
      tk.delete_at 0; tk.push(ls[m+i])
      incr.(st,ls[m+i])
      decr.(st,ls[i])
      if st.size >= k
        return [true,i+1,tk]
      end
    end
  end
  return [false]
end

def doIt(n,k,ls)

  h = n
  l = [k - 1,0].max
  a = [false]
  while (h - l > 1)
    m = (h+l) / 2
    a = good(ls,m,k)
    if a.first
      h = m
      ls = a[2]
    else
      l = m
    end
  end
  a = good(ls,h,k)
  puts "#{a[1]+1} #{a[1]+h}"

end

xs = gets.split.map(&:to_i)
n, k = xs[0], xs[1]
ls = gets.split.map(&:to_i)

st = Set.new

ls.each {|x| st.add x}

if st.size < k then
  puts "-1 -1" #cant be done
else
  doIt(n,k,ls)
end


You are given an integer $$$n$$$. In one move, you can either multiply $$$n$$$ by two or divide $$$n$$$ by $$$6$$$ (if it is divisible by $$$6$$$ without the remainder).Your task is to find the minimum number of moves needed to obtain $$$1$$$ from $$$n$$$ or determine if it's impossible to do that.You have to answer $$$t$$$ independent test cases.

The first line of the input contains one integer $$$t$$$ ($$$1 \le t \le 2 \cdot 10^4$$$) — the number of test cases. Then $$$t$$$ test cases follow.  The only line of the test case contains one integer $$$n$$$ ($$$1 \le n \le 10^9$$$).

For each test case, print the answer — the minimum number of moves needed to obtain $$$1$$$ from $$$n$$$ if it's possible to do that or -1 if it's impossible to obtain $$$1$$$ from $$$n$$$.

NoteConsider the sixth test case of the example. The answer can be obtained by the following sequence of moves from the given integer $$$15116544$$$:  Divide by $$$6$$$ and get $$$2519424$$$;  divide by $$$6$$$ and get $$$419904$$$;  divide by $$$6$$$ and get $$$69984$$$;  divide by $$$6$$$ and get $$$11664$$$;  multiply by $$$2$$$ and get $$$23328$$$;  divide by $$$6$$$ and get $$$3888$$$;  divide by $$$6$$$ and get $$$648$$$;  divide by $$$6$$$ and get $$$108$$$;  multiply by $$$2$$$ and get $$$216$$$;  divide by $$$6$$$ and get $$$36$$$;  divide by $$$6$$$ and get $$$6$$$;  divide by $$$6$$$ and get $$$1$$$.

gets.to_i.times do
	n = gets.to_i
	cnt2, cnt3 = 0, 0
	while n % 2 == 0
		n /= 2
		cnt2 += 1
	end
	while n % 3 == 0
		n /= 3
		cnt3 += 1
	end
	if n == 1 && cnt2 <= cnt3
		puts (cnt3 - cnt2) + cnt3
	else
		puts -1
	end
end

t = gets.to_i
t.times do
	n = gets.to_i
	div2 = 0
	div3 = 0
	while (n & 1) == 0
		div2 += 1
		n >>= 1
	end
	while (n % 3) == 0
		div3 += 1
		n /= 3
	end
	if n != 1 or div2 > div3
		puts "-1"
	else
		p div3*2 - div2
	end
end

def run
  n = gets.chomp.to_i

  if n == 1
    puts "0"
    return
  end

  nc = n
  twos = 0
  while true
    if nc % 2 == 0
      nc /= 2
      twos += 1
    else
      break
    end
  end

  threes = 0
  while true
    if nc % 3 == 0
      nc /= 3
      threes += 1
    else
      break
    end
  end

  if nc != 1
    puts "-1"
    return
  end

  if threes >= twos
    puts threes + threes - twos
  else
    puts "-1"
  end
end

def main
  t = gets.chomp.to_i

  t.times do
    run
  end
end

main

gets.to_i.times do
  n = gets.to_i
  ans = 0
  while n % 6 == 0 or (n != 1 and n.odd?) do
    ans += 1
    n = if n % 6 == 0 then n / 6 else n * 2 end
  end
  puts -1 if n != 1
  puts ans if n == 1
end

gets.to_i.times do
  n = gets.to_i

  d3 = 0
  while n.modulo(3).zero?
    n  /= 3
    d3 += 1
  end

  d2 = 0
  while n.modulo(2).zero?
    n  /= 2
    d2 += 1
  end

  if n > 1 || d2 > d3
    puts -1
    next
  end

  puts (d3 - d2) + d3
end


There is a frog staying to the left of the string $$$s = s_1 s_2 \ldots s_n$$$ consisting of $$$n$$$ characters (to be more precise, the frog initially stays at the cell $$$0$$$). Each character of $$$s$$$ is either 'L' or 'R'. It means that if the frog is staying at the $$$i$$$-th cell and the $$$i$$$-th character is 'L', the frog can jump only to the left. If the frog is staying at the $$$i$$$-th cell and the $$$i$$$-th character is 'R', the frog can jump only to the right. The frog can jump only to the right from the cell $$$0$$$.Note that the frog can jump into the same cell twice and can perform as many jumps as it needs.The frog wants to reach the $$$n+1$$$-th cell. The frog chooses some positive integer value $$$d$$$ before the first jump (and cannot change it later) and jumps by no more than $$$d$$$ cells at once. I.e. if the $$$i$$$-th character is 'L' then the frog can jump to any cell in a range $$$[max(0, i - d); i - 1]$$$, and if the $$$i$$$-th character is 'R' then the frog can jump to any cell in a range $$$[i + 1; min(n + 1; i + d)]$$$.The frog doesn't want to jump far, so your task is to find the minimum possible value of $$$d$$$ such that the frog can reach the cell $$$n+1$$$ from the cell $$$0$$$ if it can jump by no more than $$$d$$$ cells at once. It is guaranteed that it is always possible to reach $$$n+1$$$ from $$$0$$$.You have to answer $$$t$$$ independent test cases.

The first line of the input contains one integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases. The next $$$t$$$ lines describe test cases. The $$$i$$$-th test case is described as a string $$$s$$$ consisting of at least $$$1$$$ and at most $$$2 \cdot 10^5$$$ characters 'L' and 'R'. It is guaranteed that the sum of lengths of strings over all test cases does not exceed $$$2 \cdot 10^5$$$ ($$$\sum |s| \le 2 \cdot 10^5$$$).

For each test case, print the answer — the minimum possible value of $$$d$$$ such that the frog can reach the cell $$$n+1$$$ from the cell $$$0$$$ if it jumps by no more than $$$d$$$ at once.

NoteThe picture describing the first test case of the example and one of the possible answers:In the second test case of the example, the frog can only jump directly from $$$0$$$ to $$$n+1$$$.In the third test case of the example, the frog can choose $$$d=3$$$, jump to the cell $$$3$$$ from the cell $$$0$$$ and then to the cell $$$4$$$ from the cell $$$3$$$.In the fourth test case of the example, the frog can choose $$$d=1$$$ and jump $$$5$$$ times to the right.In the fifth test case of the example, the frog can only jump directly from $$$0$$$ to $$$n+1$$$.In the sixth test case of the example, the frog can choose $$$d=1$$$ and jump $$$2$$$ times to the right.

# coding: utf-8

t = gets.to_i
t.times {
    #         L     R
    # | 0 | | 1 | | 2 | ............ | n | | n+1 |
    # frog
    #   ------------>
    #   jump by [1, d] size, you can choose 1 for the smallest one
    # minimize size 'd'
    # range of d, min = 1 'RRR...RRRR', max = n+1 'LLL...LLL'
    # every sequence has a solution.

    # find the longest sequence of 'L' and + 1 to reach 'R' again
    max_l, l = 0, 0
    gets.chomp.split(//).each { |c|
        if c == 'R'
            if max_l < l
                max_l = l
            end
            l = 0
        else
            l += 1
        end
    }

    if max_l < l
        max_l = l # clean up
    end

    puts max_l + 1
}

tc = gets.to_i

tc.times do
    s1 =  gets.chomp
    s = "R" + s1 + "R"
    maxi = -1
    prev = 0
    l = s.size
    (1...l).each do |i|
        if(s[i] == 'R')
            now = i - prev
            maxi = [maxi,now].max
            prev = i
        end
    end
    puts maxi
end

t = gets.to_i
t.times do
  s = gets.chomp
  run_len = 0
  max_run_len = 0
  s.each_char do |c|
    case c
    when "L"
      run_len += 1
    when "R"
      max_run_len = run_len if max_run_len < run_len
      run_len = 0
    end
  end
  max_run_len = run_len if max_run_len < run_len
  puts max_run_len + 1
end

t = gets.chomp.to_i
(0...t).each do |_|
  l = "*#{gets.chomp}*"
  # puts l
  d, c = 0, 0
  (0...l.size).each do |i|
    (c+=1; next) if i.zero?
    if l[i] == 'R'
      d = [d, c].max
      c = 0
    elsif l[i] == '*'
      d = [d, c].max
    end
    c+=1
  end
  puts d
end


The "BerCorp" company has got n employees. These employees can use m approved official languages for the formal correspondence. The languages are numbered with integers from 1 to m. For each employee we have the list of languages, which he knows. This list could be empty, i. e. an employee may know no official languages. But the employees are willing to learn any number of official languages, as long as the company pays their lessons. A study course in one language for one employee costs 1 berdollar.Find the minimum sum of money the company needs to spend so as any employee could correspond to any other one (their correspondence can be indirect, i. e. other employees can help out translating).

The first line contains two integers n and m (2 ≤ n, m ≤ 100) — the number of employees and the number of languages. Then n lines follow — each employee's language list. At the beginning of the i-th line is integer ki (0 ≤ ki ≤ m) — the number of languages the i-th employee knows. Next, the i-th line contains ki integers — aij (1 ≤ aij ≤ m) — the identifiers of languages the i-th employee knows. It is guaranteed that all the identifiers in one list are distinct. Note that an employee may know zero languages. The numbers in the lines are separated by single spaces.

Print a single integer — the minimum amount of money to pay so that in the end every employee could write a letter to every other one (other employees can help out translating).

NoteIn the second sample the employee 1 can learn language 2, and employee 8 can learn language 4.In the third sample employee 2 must learn language 2.

n, m = gets.split.map(&:to_i)
$list = Array.new(n)
class Emp
  attr_reader :lang, :group, :edge
  def initialize(lang)
    @lang = lang
    @group = nil
	@edge = Array.new
  end #def init

  def edgeplus(n)
    @edge << n
  end #def edge

  def search(g)
    @group = g
    for i in @edge
	  if $list[i].group == nil
	    $list[i].search(g)
	  end
	end
  end #def search
end #class

allnone = true
for i in 0...n
  lang = gets.split.map(&:to_i).drop(1)
  $list[i] = Emp.new(lang)
  if lang.count > 0 then allnone = false end
  for j in 0...i
    if ($list[i].lang & $list[j].lang).count > 0
	  $list[j].edgeplus(i)
	  $list[i].edgeplus(j)
	end
  end
end

g = 0
for i in 0...n
  if $list[i].group == nil
    $list[i].search(g)
	g += 1
  end
end

if !allnone then g -= 1 end
puts g

input = gets.chomp.split
n = Integer(input[0])
m = Integer(input[1])
lang = []
for i in 0...n
    lang[i] = []
    lang[i] = gets.chomp.split.map{|j| Integer(j)}
end
pointer = 0
for i in 0...n
    if lang[i] != [0]
        pointer = 1
        break
    end
end
for i in 0...n
    lang[i].shift
end
boolean = []
match = []
for i in 0...n
    boolean[i] = []
    for j in 0...n
        match = (lang[i] & lang[j]).length
        if match == 0
            boolean[i].push(false)
        else
            boolean[i].push(true)
        end
    end
end

def fill_unit point, unit_id, unit, n, boolean
    if unit[point]
        return
    end

    unit[point] = unit_id
    for i in 0...n
        if boolean[point][i]
            fill_unit(i, unit_id, unit, n, boolean)
        end
    end
end

unit = Array.new(n)
for i in 0...n
    fill_unit(i, i, unit, n, boolean)
end

unit.uniq!
if pointer == 0
    puts lang.length
else
    puts unit.length - 1
end

input = gets.chomp.split
n = Integer(input[0])
m = Integer(input[1])
lang = []
for i in 0...n
    lang[i] = []
    lang[i] = gets.chomp.split.map{|j| Integer(j)}
end
pointer = 0
for i in 0...n
    if lang[i] != [0]
        pointer = 1
        break
    end
end
unit = []
for i in 0...n
    lang[i].shift
    unit.push(i)
end
boolean = []
match = []
for i in 0...n
    boolean[i] = []
    for j in 0...n
        match = (lang[i] & lang[j]).length
        if match == 0
            boolean[i].push(false)
        else
            boolean[i].push(true)
        end
    end
end

for i in 0...n
    for j in 0..i
        if boolean[i][j]
            m = unit[j]
            for k in 0...n
                if unit[k] == m
                    unit[k] = i
                end
            end
        end
    end
end
unit.uniq!
if pointer == 0
    puts lang.length
else
    puts unit.length - 1
end

#!/usr/bin/ruby1.9

n, m = STDIN.readline.split.collect {|s| s.to_i }
seen = (m+1).times.collect { false }
connected = (m+1).times.collect { {} }

mute_count = 0

n.times do
	as = STDIN.readline.split.collect {|s| s.to_i }
	count = as.shift
	if count == 0
		mute_count += 1
		next
	end
	as.length.times do |i|
		u = as[i]
		seen[u] = true
		(i..as.length-1).each do |j|
			v = as[j]
			connected[u][v] = true
			connected[v][u] = true
		end
	end
end

marked = (m+1).times.collect { false }
component_count = 0

def explore(u, marked, connected)
	marked[u] = true
	connected[u].keys.each do |v|
		next if marked[v]
		explore(v, marked, connected)
	end
end

(1..m).each do |start|
	next if marked[start] or not seen[start]
	component_count += 1
	explore(start, marked, connected)
end

puts [component_count-1, 0].max + mute_count

n,m=gets.split.map(&:to_i)
a=[]
n.times do
    k=0
    gets.split.map(&:to_i)[1..-1].each do |v|
        k+=(1<<(v-1))
    end
    a<<k
end

changed=true
while changed do
    changed=false
    for i in 0..n-1 do
        if a[i]>=0 then
            for j in i+1..n-1 do
                if a[j]>=0 and (a[i]&a[j])>0 then
                    a[i]|=a[j]
                    a[j]=-1
                    changed=true
                end
            end
        end
    end
end

z=res=0
a.each do |v|
    res+=1 if v>=0
    z+=1 if v==0
end
puts z==n ? n : res-1

n, m = gets.split(' ').collect!{|i| i.to_i}

k = []
n.times do |j|
	k[j] = gets.split(' ').collect!{|i| i.to_i}
end

needtolearn = 0

@mygroups = []

def checkinclude(int)
	@mygroups.each_index do |i|
		return i if @mygroups[i].include?(int)
	end
	return false
end

k.each do |line|
	if line[0] == 0
		needtolearn += 1
	else
		found = false
		line[1..-1].each do |lang|
			if grn = checkinclude(lang)
				@mygroups[grn] = @mygroups[grn] | line[1..-1]
				found = true
				break
			end
		end
		if !found
			@mygroups << line[1..-1]
		end
	end
end

size = @mygroups.size
size.times do |i|
	size.times do |j|
		if i != j && !(@mygroups[i] & @mygroups[j]).empty?
			@mygroups[i] = @mygroups[i] | @mygroups[j]
			@mygroups[j] = []
		end
	end
end

@mygroups.delete_if {|x| x.empty? }

learning = (@mygroups.size - 1)
learning = 0 if learning < 0

p needtolearn + learning

# Warning: This code sucks.

require "set"

n, m = gets.split.map(&:to_i)

aijs = n.times.map do
  gets.split.map(&:to_i).drop(1)
end

groups = []
aijs.each_with_index do |ai, i|
  groups[i] = Set.new ai
end

know_nothing = groups.select(&:empty?).count

loop do
  new = []
  0.upto(groups.size - 1) do |i|
    found = false
    0.upto(new.size - 1) do |j|
      if (groups[i] & new[j]).any?
        new[j] += groups[i]
        found = true
        break
      end
    end
    if !found
      new << groups[i]
    end
  end
  break if new == groups
  groups = new
end

ans = groups.count - 1
if know_nothing == groups.count
  ans += 1
end
p ans

class Node
	attr_accessor :id, :visited, :links, :exists
	def initialize id
	    @exists = true
		@id = id
		@visited = false
		@links = []
	end
	def visit nodes
		if !@visited
			@visited = true
			@links.each { |l|
				nodes[l-1].visit nodes
			}
		end
	end
end

n,m = gets.split(" ").collect! {|x| x.to_i}
nodes = [0]*n
graph = [0]*n
(1..n).each {|v|
	node = Node.new v
	nodes[v-1] = node
	graph[v-1] = node
}
zero_list = [0]*m
zeros = 0
arrs = []
(1..n).each { |k|
arr = gets.split(" ").collect! {|x| x.to_i}
arr = arr[1..-1]
if arr.size == 0
	zeros += 1
    nodes[k-1].exists = false
end
arrs.push arr
}

(1..n).each { |s|
 (s+1..n).each { |t|
	if (arrs[s-1]&arrs[t-1]).size>0
		nodes[s-1].links.push t
		nodes[t-1].links.push s
	end
 }
}

graph = graph.keep_if {|x| x.exists==true}
size = graph.size
groups = -1
p = 0
while p<size
	while p<size and graph[p].visited
		p += 1
	end
	if p<size
	 graph[p].visit nodes
	 groups += 1
	end
end

#puts "z_list: #{zero_list}"
#puts "z: #{zeros}"
if groups==-1
	puts zeros
else
	puts groups+zeros
end

n, m = gets.split.map(&:to_i)
$list = Array.new(n)
class Emp
  attr_reader :lang, :group, :edge
  def initialize(lang)
    @lang = lang
    @group = nil
	@edge = Array.new
  end #def init

  def edgeplus(n)
    @edge << n
  end #def edge

  def search(g)
    @group = g
    for i in @edge
	  if $list[i].group == nil
	    $list[i].search(g)
	  end
	end
  end #def search
end #class

for i in 0...n
  lang = gets.split.map(&:to_i).drop(1)
  $list[i] = Emp.new(lang)
  for j in 0...i
    if ($list[i].lang & $list[j].lang).count > 0
	  $list[j].edgeplus(i)
	  $list[i].edgeplus(j)
	end
  end
end

g = 0
for i in 0...n
  if $list[i].group == nil
    $list[i].search(g)
	g += 1
  end
end

puts g-1

#!/usr/bin/ruby1.9

n, m = STDIN.readline.split.collect {|s| s.to_i }
seen = (m+1).times.collect { false }
connected = (m+1).times.collect { {} }

mute_count = 0

n.times do
	as = STDIN.readline.split.collect {|s| s.to_i }
	count = as.shift
	if count == 0
		mute_count += 1
		next
	end
	as.length.times do |i|
		u = as[i]
		seen[u] = true
		(i..as.length-1).each do |j|
			v = as[j]
			connected[u][v] = true
			connected[v][u] = true
		end
	end
end

(1..m).each {|u| puts '%d: %s' % [u, connected[u].keys] }

marked = (m+1).times.collect { false }
component_count = 0

def explore(u, marked, connected)
	marked[u] = true
	connected[u].keys.each do |v|
		next if marked[v]
		explore(v, marked, connected)
	end
end

(1..m).each do |start|
	next if marked[start] or not seen[start]
	component_count += 1
	explore(start, marked, connected)
end

puts '%d components, %d mute' % [component_count, mute_count]
puts component_count-1 + mute_count

#!/usr/bin/ruby1.9

n, m = STDIN.readline.split.collect {|s| s.to_i }
seen = (m+1).times.collect { false }
connected = (m+1).times.collect { {} }

mute_count = 0

n.times do
	as = STDIN.readline.split.collect {|s| s.to_i }
	count = as.shift
	if count == 0
		mute_count += 1
		next
	end
	as.length.times do |i|
		u = as[i]
		seen[u] = true
		(i..as.length-1).each do |j|
			v = as[j]
			connected[u][v] = true
			connected[v][u] = true
		end
	end
end

marked = (m+1).times.collect { false }
component_count = 0

def explore(u, marked, connected)
	marked[u] = true
	connected[u].keys.each do |v|
		next if marked[v]
		explore(v, marked, connected)
	end
end

(1..m).each do |start|
	next if marked[start] or not seen[start]
	component_count += 1
	explore(start, marked, connected)
end

puts component_count-1 + mute_count

n,m=gets.split.map(&:to_i)
a=[]
n.times do
    k=0
    gets.split.map(&:to_i)[1..-1].each do |v|
        k+=(1<<(v-1))
    end
    a<<k
end

changed=true
while changed do
    changed=false
    for i in 0..n-1 do
        if a[i]>=0 then
            for j in i+1..n-1 do
                if a[j]>=0 and (a[i]&a[j])>0 then
                    a[i]|=a[j]
                    a[j]=-1
                    changed=true
                end
            end
        end
    end
end

res=0
a.each do |v|
    res+=1 if v>=0
end
puts res==n ? n : res-1

n,m=gets.split.map(&:to_i)
a=[]
b=[]
n.times do
    k=0
    gets.split.map(&:to_i)[1..-1].each do |v|
        k+=(1<<(v-1))
    end
    a<<k
    b<<1
end

changed=true
while changed do
    changed=false
    for i in 0..n-1 do
        if b[i]>0 then
            for j in i+1..n-1 do
                if b[j]>0 and (a[i]&a[j])>0 then
                    b[j]=0
                    a[i]|=a[j]
                    a[j]=a[i]
                    changed=true
                    break
                end
                break if changed
            end
        end
        break if changed
    end
end

res=0
b.each do |v|
    res+=v
end
puts res-1

n,m=gets.split.map(&:to_i)
a=[]
n.times do
    k=0
    gets.split.map(&:to_i)[1..-1].each do |v|
        k+=(1<<(v-1))
    end
    a<<k
end

changed=true
while changed do
    changed=false
    for i in 0..n-1 do
        if a[i]>=0 then
            for j in i+1..n-1 do
                if a[j]>=0 and (a[i]&a[j])>0 then
                    a[i]|=a[j]
                    a[j]=-1
                    changed=true
                end
            end
        end
    end
end

res=0
a.each do |v|
    res+=1 if v>=0
end
puts res-1

n, m = gets.split(' ').collect!{|i| i.to_i}

k = []
n.times do |j|
	k[j] = gets.split(' ').collect!{|i| i.to_i}
end

langs = Array.new(101, 0)
needtolearn = 0
knownlangs = []

k.each do |sot|
	if sot[0] > 0
		(1..sot[0]).each do |i|
			langs[sot[i]] += 1

			knownlangs << sot[i] if !knownlangs.include?(sot[i])
		end
	else
		needtolearn += 1
	end
end

lanmap = {}

langs.each_index do |lan|
	# needtolearn += 1 if lan == 1

	if langs[lan] > 0
		lanmap[lan] = {} if !lanmap[lan]
		knownlangs.each do |kn|
			lanmap[lan][kn] = false if kn != lan
		end
	end
end

knownlangs.each do |kn|
	mylangs = [kn]
	k.each do |sot|
		if sot[0] > 0
			(1..sot[0]).each do |i|
				mylangs << sot[i] if sot[1..-1].include?(kn) && !mylangs.include?(sot[i])

				# lanmap[kn][sot[i]] = true if sot[1..-1].include?(kn)
			end
		end
	end

	mylangs.each do |ln1|
		mylangs.each do |ln2|
			lanmap[ln1][ln2] = true
		end
	end
end

allok = false
learning = 0

while !allok
	knownlangs[1..-1].each do |lan2|
		if lanmap[knownlangs[0]][lan2] == false
			p lan2
			learning += 1
			lanmap[lan2].each_key do |lan3|
				lanmap[knownlangs[0]][lan3] = true if lanmap[lan2][lan3]
			end
		end
		allok = true if lan2 == knownlangs[-1]
	end
end

p lanmap

n, m = gets.split(' ').collect!{|i| i.to_i}

k = []
n.times do |j|
	k[j] = gets.split(' ').collect!{|i| i.to_i}
end

langs = Array.new(101, 0)
needtolearn = 0

@mygroups = []

def checkinclude(int)
	@mygroups.each_index do |i|
		return i if @mygroups[i].include?(int)
	end
	return false
end

k.each do |line|
	if line[0] == 0
		needtolearn += 1
	else
		found = false
		line[1..-1].each do |lang|
			if grn = checkinclude(lang)
				# p grn
				# p @mygroups[grn].to_s
				# p line[1..-1].to_s
				@mygroups[grn] = @mygroups[grn] | line[1..-1]
				found = true
				break
			end
		end
		if !found
			@mygroups << line[1..-1]
		end
	end
end

size = @mygroups.size
size.times do |i|
	size.times do |j|
		if i != j && !(@mygroups[i] & @mygroups[j]).empty?
			@mygroups[i] = @mygroups[i] | @mygroups[j]
			@mygroups[j] = []
		end
	end
end

@mygroups.delete_if {|x| x.empty? }

p needtolearn + (@mygroups.size - 1)
# p needtolearn
# p @mygroups.to_s

# Warning: This code sucks.

require "set"

n, m = gets.split.map(&:to_i)

aijs = n.times.map do
  gets.split.map(&:to_i).drop(1)
end

groups = []
aijs.each_with_index do |ai, i|
  groups[i] = Set.new ai
end

know_nothing = groups.select(&:empty?).count

loop do
  new = []
  0.upto(groups.size - 1) do |i|
    found = false
    0.upto(new.size - 1) do |j|
      if (groups[i] & new[j]).any?
        new[j] += groups[i]
        found = true
        break
      end
    end
    if !found
      new << groups[i]
    end
  end
  break if new == groups
  groups = new
end

ans = groups.count - 1
if know_nothing > 0
  ans += 1
end
p ans

# Warning: This code sucks.

require "set"

n, m = gets.split.map(&:to_i)

aijs = n.times.map do
  gets.split.map(&:to_i).drop(1)
end

groups = []
aijs.each_with_index do |ai, i|
  groups[i] = Set.new ai
end

know_nothing = groups.select(&:empty?).count

loop do
  new = []
  0.upto(groups.size - 1) do |i|
    found = false
    0.upto(new.size - 1) do |j|
      if (groups[i] & new[j]).any?
        new[j] += groups[i]
        found = true
        break
      end
    end
    if !found
      new << groups[i]
    end
  end
  break if new == groups
  groups = new
end

ans = groups.count - 1
if know_nothing > 1
  ans += 1
end
p ans

# Warning: This code sucks.

require "set"

n, m = gets.split.map(&:to_i)

aijs = n.times.map do
  gets.split.map(&:to_i).drop(1)
end

groups = []
aijs.each_with_index do |ai, i|
  groups[i] = Set.new ai
end

loop do
  new = []
  0.upto(groups.size - 1) do |i|
    found = false
    0.upto(new.size - 1) do |j|
      if (groups[i] & new[j]).any?
        new[j] += groups[i]
        found = true
        break
      end
    end
    if !found
      new << groups[i]
    end
  end
  break if new == groups
  groups = new
end

p groups.count - 1

class Node
	attr_accessor :id, :visited, :links
	def initialize id
		@id = id
		@visited = false
		@links = []
	end
	def visit nodes
		if !@visited
			@visited = true
			@links.each { |l|
				nodes[l-1].visit nodes
			}
		end
	end
end

n,m = gets.split(" ").collect! {|x| x.to_i}
nodes = [0]*n
(1..n).each {|v|
	nodes[v-1] = Node.new v
}
zero_list = [0]*m
zeros = 0
arrs = []
(1..n).each {
arr = gets.split(" ").collect! {|x| x.to_i}
arr = arr[1..-1]
if arr.size == 0
	zeros += 1
end
arrs.push arr
}

(1..n).each { |s|
 (s+1..n).each { |t|
	if (arrs[s-1]&arrs[t-1]).size>0
		nodes[s-1].links.push t
		nodes[t-1].links.push s
	end
 }
}

groups = -1
p = 0
while p<n
	while p<n and nodes[p].visited
		p += 1
	end
	if p<n
	 nodes[p].visit nodes
	 groups += 1
	end
end

#puts "z_list: #{zero_list}"
#puts "z: #{zeros}"
puts groups

class Node
	attr_accessor :id, :visited, :links
	def initialize id
		@id = id
		@visited = false
		@links = []
	end
	def visit nodes
		if !@visited
			@visited = true
			@links.each { |l|
				nodes[l-1].visit nodes
			}
		end
	end
end

n,m = gets.split(" ").collect! {|x| x.to_i}
nodes = [0]*m
(1..m).each {|v|
	nodes[v-1] = Node.new v
}
zero_list = [0]*m
zeros = 0
(1..n).each {
arr = gets.split(" ").collect! {|x| x.to_i}
arr = arr[1..-1]
if arr.size == 0
	zeros += 1
end
arr.each { |s|
	arr.each { |t|
		zero_list[s-1]=1
		zero_list[t-1]=1
		if s!=t

			if !nodes[s-1].links.include? t
				nodes[s-1].links.push t
				nodes[t-1].links.push s
			end
		end
	}
}
}

groups = 0
p = 0
while p<m
	while p<m and nodes[p].visited
		p += 1
	end
	if p<m
	 nodes[p].visit nodes
	 groups += 1
	end
end

sum = m
zero_list.each { |v|
	sum -= v
}

#puts "z_list: #{zero_list}"
#puts "z: #{zeros}"
puts zeros+groups-1-sum


You are given four integer values $$$a$$$, $$$b$$$, $$$c$$$ and $$$m$$$.Check if there exists a string that contains:   $$$a$$$ letters 'A';  $$$b$$$ letters 'B';  $$$c$$$ letters 'C';  no other letters;  exactly $$$m$$$ pairs of adjacent equal letters (exactly $$$m$$$ such positions $$$i$$$ that the $$$i$$$-th letter is equal to the $$$(i+1)$$$-th one).

The first line contains a single integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of testcases. Each of the next $$$t$$$ lines contains the description of the testcase — four integers $$$a$$$, $$$b$$$, $$$c$$$ and $$$m$$$ ($$$1 \le a, b, c \le 10^8$$$; $$$0 \le m \le 10^8$$$).

For each testcase print "YES" if there exists a string that satisfies all the requirements. Print "NO" if there are no such strings. You may print every letter in any case you want (so, for example, the strings yEs, yes, Yes and YES will all be recognized as positive answer).

NoteIn the first testcase strings "ABCAB" or "BCABA" satisfy the requirements. There exist other possible strings.In the second testcase there's no way to put adjacent equal letters if there's no letter that appears at least twice.In the third testcase string "CABBCC" satisfies the requirements. There exist other possible strings.

gets.to_i.times do

*abc, m = gets.split.map!(&:to_i)

abc.sort!
m_max = abc.sum - 3
m_min = abc[-1] - 1 - abc[0] - abc[1]
m_min = 0 if m_min < 0

puts m.between?(m_min, m_max) ? :YES : :NO

end


Famil Door wants to celebrate his birthday with his friends from Far Far Away. He has n friends and each of them can come to the party in a specific range of days of the year from ai to bi. Of course, Famil Door wants to have as many friends celebrating together with him as possible.Far cars are as weird as Far Far Away citizens, so they can only carry two people of opposite gender, that is exactly one male and one female. However, Far is so far from here that no other transportation may be used to get to the party.Famil Door should select some day of the year and invite some of his friends, such that they all are available at this moment and the number of male friends invited is equal to the number of female friends invited. Find the maximum number of friends that may present at the party.

The first line of the input contains a single integer n (1 ≤ n ≤ 5000) — then number of Famil Door's friends. Then follow n lines, that describe the friends. Each line starts with a capital letter 'F' for female friends and with a capital letter 'M' for male friends. Then follow two integers ai and bi (1 ≤ ai ≤ bi ≤ 366), providing that the i-th friend can come to the party from day ai to day bi inclusive.

Print the maximum number of people that may come to Famil Door's party.

NoteIn the first sample, friends 3 and 4 can come on any day in range [117, 128].In the second sample, friends with indices 3, 4, 5 and 6 can come on day 140.

n = gets.to_i
M = [0]*10000
F = [0]*10000
n.times do
  a = gets.split(" ")
  gen = a.shift
  q, w = a.map(&:to_i)
  ary = eval gen
  (q..w).each {|d| ary[d] += 1 }
end

p 2*(1..366).map{|i| [M[i], F[i]].min }.max

n = gets.chomp.to_i
males = Array.new(367) { 0 }
females = Array.new(367) { 0 }
n.times do
  g, a, b = gets.chomp.split.map { |e| e.match(/\d/) ? e.to_i : e }
  (a..b).each { |i| g == 'M' ? males[i] += 1 : females[i] += 1 }
end
ans = 0
(0..367).each do |i|
  ans = [ans, [males[i], females[i]].map(&:to_i).min * 2].max
end
puts ans

n = gets.to_i
md = Array.new(370, 0)
fd = Array.new(370, 0)

n.times do
  g, s, t = gets.split
  s = s.to_i
  t = t.to_i
  if g == 'M'
    for i in s..t
      md[i] += 1
    end
  else
    for i in s..t
      fd[i] += 1
    end
  end
end
ans = 0

370.times do |i|
  if [md[i], fd[i]].min > ans
    ans = [md[i], fd[i]].min
  end
end
puts ans*2

n = gets.chomp.to_i
gs = []
as = []
bs = []
n.times do
  g, a, b = gets.chomp.split.map { |x| x =~ /[MF]/ ? x : x.to_i }
  gs << g
  as << a
  bs << b
end

ans = 0
for d in 1..366
  m = 0
  f = 0
  for i in 0...n
    if gs[i] == 'M'
      m += 1 if as[i] <= d && d <= bs[i]
    else
      f += 1 if as[i] <= d && d <= bs[i]
    end
  end
  ans = [ans, [m, f].min * 2].max
end

puts ans

n = gets.to_i
ms = []
fs = []
for i in 0...n
  g, s, e = gets.split(' ')
  s = s.to_i
  e = e.to_i

  for j in s..e
    if g == 'M'
      ms[j] ||= 0
      ms[j] += 1
    else
      fs[j] ||= 0
      fs[j] += 1
    end
  end
end

maxatt = 0
maxi = 0
for i in 1..366
  att = [ms[i].to_i, fs[i].to_i].min
  if att > maxatt
    maxatt = att
    maxi = i
  end
end

puts maxatt*2

n = gets.to_i
a = Array.new(367)
n.times do
  g, b, e = gets.split
  (b.to_i..e.to_i).each do |i|
    a[i] ||= []
    a[i] << g
  end
end
b = a.map do |suba|
  if suba.nil?
    0
  else
    f, m = 0, 0
    suba.each do |x|
      if x == 'F'
        f += 1
      elsif x == 'M'
        m += 1
      end
    end
    [f, m].min
  end
end
puts b.max * 2


There is little time left before the release of the first national operating system BerlOS. Some of its components are not finished yet — the memory manager is among them. According to the developers' plan, in the first release the memory manager will be very simple and rectilinear. It will support three operations:   alloc n — to allocate n bytes of the memory and return the allocated block's identifier x;  erase x — to erase the block with the identifier x;  defragment — to defragment the free memory, bringing all the blocks as close to the beginning of the memory as possible and preserving their respective order; The memory model in this case is very simple. It is a sequence of m bytes, numbered for convenience from the first to the m-th.The first operation alloc n takes as the only parameter the size of the memory block that is to be allocated. While processing this operation, a free block of n successive bytes is being allocated in the memory. If the amount of such blocks is more than one, the block closest to the beginning of the memory (i.e. to the first byte) is prefered. All these bytes are marked as not free, and the memory manager returns a 32-bit integer numerical token that is the identifier of this block. If it is impossible to allocate a free block of this size, the function returns NULL.The second operation erase x takes as its parameter the identifier of some block. This operation frees the system memory, marking the bytes of this block as free for further use. In the case when this identifier does not point to the previously allocated block, which has not been erased yet, the function returns ILLEGAL_ERASE_ARGUMENT.The last operation defragment does not have any arguments and simply brings the occupied memory sections closer to the beginning of the memory without changing their respective order.In the current implementation you are to use successive integers, starting with 1, as identifiers. Each successful alloc operation procession should return following number. Unsuccessful alloc operations do not affect numeration.You are to write the implementation of the memory manager. You should output the returned value for each alloc command. You should also output ILLEGAL_ERASE_ARGUMENT for all the failed erase commands.

The first line of the input data contains two positive integers t and m (1 ≤ t ≤ 100;1 ≤ m ≤ 100), where t — the amount of operations given to the memory manager for processing, and m — the available memory size in bytes. Then there follow t lines where the operations themselves are given. The first operation is alloc n (1 ≤ n ≤ 100), where n is an integer. The second one is erase x, where x is an arbitrary 32-bit integer numerical token. The third operation is defragment.

Output the sequence of lines. Each line should contain either the result of alloc operation procession , or ILLEGAL_ERASE_ARGUMENT as a result of failed erase operation procession. Output lines should go in the same order in which the operations are processed. Successful procession of alloc operation should return integers, starting with 1, as the identifiers of the allocated blocks.

6 10
alloc 5
alloc 3
erase 1
alloc 6
defragment
alloc 6

input = gets.chomp.split.map do |x|
    Integer(x)
end

n = input[0]
m = input[1]

memory = Array.new(m) { |i| 0 }
next_id = 1

def find_and_fill_block(memory, len, next_id)
    head = 0
    for i in 0...memory.length
        if head <= i - len
            break
        end

        if memory[i] != 0
            head = i + 1
        end
    end
    if head + len <= memory.length
        for i in 0...len
            memory[head + i] = next_id
        end
        return true
    end

    return false
end

def erase_block(memory, id)
    flag = false
    for i in 0...memory.length
        if memory[i] == id
            memory[i] = 0
            flag = true
        end
    end

    return flag
end

def defragment(memory)
    j = 0
    for i in 0...memory.length
        if memory[i] != 0
            memory[j] = memory[i]
            j += 1
        end
    end
    for i in j...memory.length
        memory[i] = 0
    end
end

for i in 0...n
    input = gets.chomp.split
    command = input[0]
    if command[0] == 'a'
        len = Integer(input[1])
        ret = find_and_fill_block(memory, len, next_id)
        if ret
            puts next_id
            next_id += 1
        else
            puts "NULL"
        end
    elsif command[0] == 'e'
        cur_id = Integer(input[1])
        ret = cur_id != 0 && erase_block(memory, cur_id)
        if !ret
            puts "ILLEGAL_ERASE_ARGUMENT"
        end
    else
        defragment(memory)
    end
end

data = gets.chomp.split
t = Integer(data[0])
w = Integer(data[1])
task = []
for i in 0...t
    task[i] = gets.chomp
end

memory = []
for i in 0...w
    memory[i] = 0
end

def getInt(string)
    string = string.split
    integer = Integer(string[1])
    return integer
end
def allocate(amount, array)
    success = false
    endIndex = 0
    count = 0
    if amount == 1
        for i in 0...array.length
            if array[i] == 0
                endIndex = i - 1
                success = true
                break
            end
        end
    else
        if array.length > 1
            for i in 0...array.length - 1
                if array[i] == array[i + 1] && array[i] == 0
                    count += 1
                else
                    if count + 1 >= amount
                        endIndex = i
                        success = true
                        break
                    else
                        count = 0
                    end
                end
                if count + 1 >= amount
                    endIndex = i
                    success = true
                    break
                end
            end
        else
            if amount == 1 && array.length == 1
                if array[0] == 0
                    array[0] = 1
                    success = true
                    endIndex = -1
                end
            end
        end
    end
    if success
        return endIndex
    else
        return "NULL"
    end
end

def erase(identifier, array)
    for i in 0...array.length
        if array[i] == identifier
            array[i] = 0
        end
    end
    return array
end

def defragment(array)
    count = 0
    i = 0
    while i <= array.length
        if array[i] == 0
            array.delete_at(i)
            count += 1
        else
            i += 1
        end
    end
    count.times{ array.push(0)}
    return array
end

cast = Hash.new
key = 0
for i in 0...t
    if task[i][0] == "a"
        int = getInt(task[i])
        endIndex = allocate(int, memory)
        if endIndex == "NULL"
            puts "NULL"
        else
            key += 1
            cast[key] = int
            for i in endIndex - int + 2..endIndex + 1
                memory[i] = key
            end
            puts key
        end
    elsif task[i][0] == "e"
        int = getInt(task[i])
        if int <= key && int > 0
            value = cast[int]
            if value != nil
                memory = erase(int, memory)
                cast.delete(int)
            else
                puts "ILLEGAL_ERASE_ARGUMENT"
            end
        else
            puts "ILLEGAL_ERASE_ARGUMENT"
        end
    else
        memory = defragment(memory)
    end
end

n, m = gets.split.map(&:to_i)
identifiers = {}
memory_blocks = {}
identifier = 1

n.times do
	command = gets.split(' ')
	case command[0]
		when "alloc"
			start_index = 0
			block_size = command[1].to_i
			fit = false
			while memory_blocks[start_index]
				start_index += memory_blocks[start_index]
			end
			while start_index + block_size <= m
				break if block_size == m && !memory_blocks.empty?
				check = memory_blocks.select { |k, v| (k < start_index + block_size) && (k >= start_index) }
				if check.empty?
					memory_blocks[start_index] = block_size
					identifiers[identifier] = start_index
					puts identifier
					identifier += 1
					fit = true
					# puts "memory_blocks is #{memory_blocks}"
					# puts "identifiers is #{identifiers}"
					break
				else
					next_index = check.min
					start_index = next_index[0] + memory_blocks[next_index[0]]
				end
			end
			puts "NULL" unless fit
		when "erase"
			d_iden = command[1].to_i
			iden_index = identifiers[d_iden]
			if iden_index.nil?
				puts "ILLEGAL_ERASE_ARGUMENT"
			else
				identifiers.delete(d_iden)
				memory_blocks.delete(iden_index)
				# puts "memory_blocks is #{memory_blocks}"
				# puts "identifiers is #{identifiers}"
			end
		else # defragment
			start_index = 0
			copy = {}
			memory_blocks.size.times do
				lowest = memory_blocks.min
				copy[start_index] = lowest[1]
				identifiers[identifiers.key(lowest[0])] = start_index
				start_index += lowest[1]
				memory_blocks.delete(lowest[0])
			end
			memory_blocks = copy
			# puts "memory_blocks is #{memory_blocks}"
			# puts "identifiers is #{identifiers}"
		end
end

class MemManager

  EMPTY = 0

  def initialize(size)
    @size = size
    @mem = Array.new(size, EMPTY)
    @id = 1
    @used_ids = {}
  end

  def get_mem
    @mem.to_s
  end

  # returns block id or 0 if cannot alloc block
  def alloc(len)
    ind = find_empty_block(len)
    if ind >= 0
      fill_block(ind, len, @id)
      @used_ids[@id] = [ind, len]
      @id += 1
      return @id - 1
    end
    0
  end

  def erase(id)
    if @used_ids[id]
      ind, len = @used_ids[id]
      fill_block(ind, len, EMPTY)
      @used_ids.delete(id)
      #p @used_ids
      return true
    end
    false
  end

  def defrag
    # get keys in order they are in mem
    keys = @mem.uniq
    keys.delete(0)
    # move 0-s to the end of @mem
    @mem = @mem.delete_if {|x| x == 0}
    @mem << 0 while @mem.size < @size
    # relocate @used_ids
    cur_ind = 0
    keys.each do |id|
       ind, len = @used_ids[id]
       ind = cur_ind
       cur_ind += len
       @used_ids[id] = [ind, len]
    end
  end

private

  # returns -1 if cannot find empty block of length n
  def find_empty_block(n)
    start = 0
    while start <= @size - n
      if @mem[start] != EMPTY
        start += 1
        next
      end
      i = 0
      while @mem[start + i] == EMPTY
        i += 1
      end
      return start if i >= n
      start += i
    end
    -1
  end

  def fill_block(ind, len, value)
    @mem.fill(value, ind, len)
  end
end

if __FILE__ == $0
  t, m = gets.split.collect {|x| Integer(x)}
  mm = MemManager.new(m)
  while line = gets
    line.chomp!
    if line.start_with?('alloc')
      a = line.scan(/\d+/)
      n = Integer(a[0])
      id = mm.alloc(n)
      puts (id == 0) ? "NULL" : id
    elsif line.start_with?('erase')
      a = line.scan(/\d+/)
      n = Integer(a[0])
      puts "ILLEGAL_ERASE_ARGUMENT" unless mm.erase(n)
    elsif line.start_with?('defragment')
      mm.defrag
    end
  end
end

input = gets.chomp.split.map do |x|
    Integer(x)
end

n = input[0]
m = input[1]

memory = Array.new(m) { |i| 0 }
next_id = 1

def find_and_fill_block(memory, len, next_id)
    head = 0
    for i in 0...memory.length
        if head <= i - len
            break
        end

        if memory[i] != 0
            head = i + 1
        end
    end
    if head + len <= memory.length
        for i in 0...len
            memory[head + i] = next_id
        end
        return true
    end

    return false
end

def erase_block(memory, id)
    flag = false
    for i in 0...memory.length
        if memory[i] == id
            memory[i] = 0
            flag = true
        end
    end

    return flag
end

def defragment(memory)
    j = 0
    for i in 0...memory.length
        if memory[i] != 0
            memory[j] = memory[i]
            j += 1
        end
    end
    for i in j...memory.length
        memory[i] = 0
    end
end

for i in 0...n
    input = gets.chomp.split
    command = input[0]
    if command[0] == 'a'
        len = Integer(input[1])
        ret = find_and_fill_block(memory, len, next_id)
        if ret
            puts next_id
            next_id += 1
        else
            puts "NULL"
        end
    elsif command[0] == 'e'
        cur_id = Integer(input[1])
        ret = erase_block(memory, cur_id)
        if !ret
            puts "ILLEGAL_ERASE_ARGUMENT"
        end
    else
        defragment(memory)
    end
    puts memory
end

input = gets.chomp.split.map do |x|
    Integer(x)
end

n = input[0]
m = input[1]

memory = Array.new(m) { |i| 0 }
next_id = 1

def find_and_fill_block(memory, len, next_id)
    head = 0
    for i in 0...memory.length
        if head <= i - len
            break
        end

        if memory[i] != 0
            head = i + 1
        end
    end
    if head + len <= memory.length
        for i in 0...len
            memory[head + i] = next_id
        end
        return true
    end

    return false
end

def erase_block(memory, id)
    flag = false
    for i in 0...memory.length
        if memory[i] == id
            memory[i] = 0
            flag = true
        end
    end

    return flag
end

def defragment(memory)
    j = 0
    for i in 0...memory.length
        if memory[i] != 0
            memory[j] = memory[i]
            j += 1
        end
    end
    for i in j...memory.length
        memory[i] = 0
    end
end

for i in 0...n
    input = gets.chomp.split
    command = input[0]
    if command[0] == 'a'
        len = Integer(input[1])
        ret = find_and_fill_block(memory, len, next_id)
        if ret
            puts next_id
            next_id += 1
        else
            puts "NULL"
        end
    elsif command[0] == 'e'
        cur_id = Integer(input[1])
        ret = erase_block(memory, cur_id)
        if !ret
            puts "ILLEGAL_ERASE_ARGUMENT"
        end
    else
        defragment(memory)
    end
end

data = gets.chomp.split
t = Integer(data[0])
w = Integer(data[1])
task = []
for i in 0...t
    task[i] = []
    task[i] = gets.chomp
end

memory = []
for i in 0...w
    memory[i] = 0
end

def allocate(amount, array)
    success = false
    endIndex = 0
    count = 0
    for i in 0...array.length - 1
        if array[i] == array[i + 1] && array[i] == 0
            count += 1
        else
            if count + 1 >= amount
                endIndex = i
                success = true
                break
            else
                count = 0
            end
        end
        if count + 1 >= amount
            endIndex = i
            success = true
            break
        end
    end
    if success
        return endIndex
    else
        return "NULL"
    end
end

def erase(identifier, array)
    for i in 0...array.length
        if array[i] == identifier
            array[i] = 0
        end
    end
    return array
end

def defragment(array)
    count = 0
    i = 0
    while i <= array.length
        if array[i] == 0
            array.delete_at(i)
            count += 1
        else
            i += 1
        end
    end
    count.times{ array.push(0)}
    return array
end

cast = Hash.new
key = 0
for i in 0...t
    if task[i][0] == "a"
        amount = Integer(task[i][task[i].length - 1])
        endIndex = allocate(amount, memory)
        if endIndex == "NULL"
            puts "NULL"
        else
            key += 1
            cast[key] = amount
            for i in endIndex - amount + 2..endIndex + 1
                memory[i] = key
            end
            puts key
        end
    elsif task[i][0] == "e"
        identifier = Integer(task[i][task[i].length - 1])
        if identifier <= key
            memory = erase(identifier, memory)
            cast[identifier] = -1
        else
            puts "ILLEGAL_ERASE_ARGUMENT"
        end
    else
        memory = defragment(memory)
    end
end

data = gets.chomp.split
t = Integer(data[0])
w = Integer(data[1])
task = []
for i in 0...t
    task[i] = []
    task[i] = gets.chomp
end

memory = []
for i in 0...w
    memory[i] = 0
end

def allocate(amount, array)
    success = false
    endIndex = 0
    count = 0
    if array.length > 1
        for i in 0...array.length - 1
            if array[i] == array[i + 1] && array[i] == 0
                count += 1
            else
                if count + 1 >= amount
                    endIndex = i
                    success = true
                    break
                else
                    count = 0
                end
            end
            if count + 1 >= amount
                endIndex = i
                success = true
                break
            end
        end
    else
        if amount == 1 && array.length == 1
            if array[0] == 0
                array[0] = 1
                success = true
                endIndex = -1
            end
        end
    end
    if success
        return endIndex
    else
        return "NULL"
    end
end

def erase(identifier, array)
    for i in 0...array.length
        if array[i] == identifier
            array[i] = 0
        end
    end
    return array
end

def defragment(array)
    count = 0
    i = 0
    while i <= array.length
        if array[i] == 0
            array.delete_at(i)
            count += 1
        else
            i += 1
        end
    end
    count.times{ array.push(0)}
    return array
end

cast = Hash.new
key = 0
for i in 0...t
    if task[i][0] == "a"
        amount = Integer(task[i][task[i].length - 1])
        endIndex = allocate(amount, memory)
        if endIndex == "NULL"
            puts "NULL"
        else
            key += 1
            cast[key] = amount
            for i in endIndex - amount + 2..endIndex + 1
                memory[i] = key
            end
            puts key
        end
    elsif task[i][0] == "e"
        negetive = task[i][task[i].length - 2]
        if negetive == "-"
            identifier = 0 - Integer(task[i][task[i].length - 1])
        else
            identifier = Integer(task[i][task[i].length - 1])
        end
        if identifier <= key && identifier > 0
            value = cast[identifier]
            if value != nil
                memory = erase(identifier, memory)
                cast.delete(identifier)
            else
                puts "ILLEGAL_ERASE_ARGUMENT"
            end
        else
            puts "ILLEGAL_ERASE_ARGUMENT"
        end
    else
        memory = defragment(memory)
    end
end

n, m = gets.split.map(&:to_i)
identifiers = {}
memory_blocks = {}
start_index = 0
identifier = 1

n.times do
	command = gets.split(' ')
	case command[0]
		when "alloc"
			block_size = command[1].to_i
			fit = false
			while memory_blocks[start_index]
				start_index += memory_blocks[start_index]
			end
			while start_index + block_size <= m
				break if block_size == m && !memory_blocks.empty?
				check = memory_blocks.select { |k, v| (k < start_index + block_size) && (k >= start_index) }
				if check.empty?
					memory_blocks[start_index] = block_size
					identifiers[identifier] = start_index
					puts identifier
					identifier += 1
					start_index += block_size
					fit = true
					break
				else
					next_index = check.min
					start_index = next_index[0] + memory_blocks[next_index[0]]
				end
			end
			puts "NULL" unless fit
		when "erase"
			d_iden = command[1].to_i
			iden_index = identifiers[d_iden]
			if iden_index.nil?
				puts "ILLEGAL_ERASE_ARGUMENT"
			else
				identifiers.delete(d_iden)
				memory_blocks.delete(iden_index)
				start_index = iden_index
			end
		else # defragment
			start_index = 0
			copy = {}
			memory_blocks.size.times do
				lowest = memory_blocks.min
				copy[start_index] = lowest[1]
				identifiers[identifiers.key(lowest[0])] = start_index
				start_index += lowest[1]
				memory_blocks.delete(lowest[0])
			end
			memory_blocks = copy
		end
end

n, m = gets.split.map(&:to_i)
identifiers = {}
memory_blocks = {}
start_index = 0
identifier = 1

n.times do
	command = gets.split(' ')
	case command[0]
		when "alloc"
			block_size = command[1].to_i
			fit = false
			while memory_blocks[start_index]
				start_index += memory_blocks[start_index]
			end
			while start_index + block_size <= m
				break if block_size == m && !memory_blocks.empty?
				check = memory_blocks.select { |k, v| (k < start_index + block_size) && (k >= start_index) }
				if check.empty?
					memory_blocks[start_index] = block_size
					identifiers[identifier] = start_index
					puts identifier
					identifier += 1
					start_index += block_size
					fit = true
					puts "memory_blocks is #{memory_blocks}"
					puts "identifiers is #{identifiers}"
					break
				else
					next_index = check.min
					start_index = next_index[1] + memory_blocks[next_index[0]]
				end
			end
			puts "NULL" unless fit
		when "erase"
			d_iden = command[1].to_i
			iden_index = identifiers[d_iden]
			if iden_index.nil?
				puts "ILLEGAL_ERASE_ARGUMENT"
			else
				identifiers.delete(d_iden)
				memory_blocks.delete(iden_index)
				start_index = iden_index
				puts "start_index is #{start_index}"
				puts "memory_blocks is #{memory_blocks}"
				puts "identifiers is #{identifiers}"
			end
		else # defragment
			start_index = 0
			copy = {}
			memory_blocks.size.times do
				lowest = memory_blocks.min
				copy[start_index] = lowest[1]
				identifiers[identifiers.key(lowest[0])] = start_index
				start_index += lowest[1]
				memory_blocks.delete(lowest[0])
			end
			memory_blocks = copy
			puts "memory_blocks is #{memory_blocks}"
			puts "identifiers is #{identifiers}"
		end
end

n, m = gets.split.map(&:to_i)
identifiers = {}
memory_blocks = {}
start_index = 0
identifier = 1

n.times do
	command = gets.split(' ')
	case command[0]
		when "alloc"
			block_size = command[1].to_i
			fit = false
			while memory_blocks[start_index]
				start_index += memory_blocks[start_index]
			end
			while start_index + block_size <= m
				break if block_size == m && !memory_blocks.empty?
				check = memory_blocks.select { |k, v| (k < start_index + block_size) && (k >= start_index) }
				if check.empty?
					memory_blocks[start_index] = block_size
					identifiers[identifier] = start_index
					puts identifier
					identifier += 1
					start_index += block_size
					fit = true
					break
				else
					next_index = check.min
					start_index = next_index[1] + memory_blocks[next_index[0]]
				end
			end
			puts "NULL" unless fit
		when "erase"
			d_iden = command[1].to_i
			iden_index = identifiers[d_iden]
			if iden_index.nil?
				puts "ILLEGAL_ERASE_ARGUMENT"
			else
				identifiers.delete(d_iden)
				memory_blocks.delete(iden_index)
				start_index = iden_index
			end
		else # defragment
			start_index = 0
			copy = {}
			memory_blocks.size.times do
				lowest = memory_blocks.min
				copy[start_index] = lowest[1]
				identifiers[identifiers.key(lowest[0])] = start_index
				start_index += lowest[1]
				memory_blocks.delete(lowest[0])
			end
			memory_blocks = copy
		end
end

n, m = gets.split.map(&:to_i)
identifiers = {}
memory_blocks = {}
start_index = 0
identifier = 1

n.times do
	command = gets.split(' ')
	case command[0]
		when "alloc"
			block_size = command[1].to_i
			fit = false
			while memory_blocks[start_index]
				start_index += memory_blocks[start_index]
			end
			while start_index + block_size <= m
				check = memory_blocks.select { |k, v| (k < start_index + block_size) && (k >= start_index) }
				if check.empty?
					memory_blocks[start_index] = block_size
					identifiers[identifier] = start_index
					puts identifier
					identifier += 1
					start_index += block_size
					fit = true
					break
				else
					next_index = check.min
					start_index = next_index[1] + memory_blocks[next_index[0]]
				end
			end
			puts "NULL" unless fit
		when "erase"
			d_iden = command[1].to_i
			iden_index = identifiers[d_iden]
			if iden_index.nil?
				puts "ILLEGAL_ERASE_ARGUMENT"
			else
				identifiers.delete(d_iden)
				memory_blocks.delete(iden_index)
				start_index = iden_index
			end
		else # defragment
			start_index = 0
			copy = memory_blocks
			memory_blocks.size.times do
				lowest = copy.min
				memory_blocks[start_index] = lowest[1]
				identifiers[identifiers.key(lowest[0])] = start_index
				start_index += lowest[1]
				copy.delete(lowest[0])
				memory_blocks.delete(lowest[0])
			end
		end
end

n, m = gets.split.map(&:to_i)
identifiers = {}
memory_blocks = {}
identifier = 1

n.times do
	command = gets.split(' ')
	case command[0]
		when "alloc"
			start_index = 0
			block_size = command[1].to_i
			fit = false
			while memory_blocks[start_index]
				start_index += memory_blocks[start_index]
			end
			while start_index + block_size <= m
				break if block_size == m && !memory_blocks.empty?
				check = memory_blocks.select { |k, v| (k < start_index + block_size) && (k >= start_index) }
				if check.empty?
					memory_blocks[start_index] = block_size
					identifiers[identifier] = start_index
					puts identifier
					identifier += 1
					fit = true
					puts "memory_blocks is #{memory_blocks}"
					puts "identifiers is #{identifiers}"
					break
				else
					next_index = check.min
					start_index = next_index[0] + memory_blocks[next_index[0]]
				end
			end
			puts "NULL" unless fit
		when "erase"
			d_iden = command[1].to_i
			iden_index = identifiers[d_iden]
			if iden_index.nil?
				puts "ILLEGAL_ERASE_ARGUMENT"
			else
				identifiers.delete(d_iden)
				memory_blocks.delete(iden_index)
				puts "memory_blocks is #{memory_blocks}"
				puts "identifiers is #{identifiers}"
			end
		else # defragment
			start_index = 0
			copy = {}
			memory_blocks.size.times do
				lowest = memory_blocks.min
				copy[start_index] = lowest[1]
				identifiers[identifiers.key(lowest[0])] = start_index
				start_index += lowest[1]
				memory_blocks.delete(lowest[0])
			end
			memory_blocks = copy
			puts "memory_blocks is #{memory_blocks}"
			puts "identifiers is #{identifiers}"
		end
end