from sys import *
from math import *
from random import *
from socket import *
from time import *

import struct

def euclid(a, b):
	if b == 0:
		if a >= 0:
			return [a,1,0]
		else:
			return [-a,-1,0]
	else:
		r0 = a
		r1 = b
		x0 = 1
		x1 = 0
		y0 = 0
		y1 = 1
		while r1 != 0:
			q = r0/r1
			r2 = r0 - q*r1
			x2 = x0 - q*x1
			y2 = y0 - q*y1
			r0 = r1
			r1 = r2
			x0 = x1
			x1 = x2
			y0 = y1
			y1 = y2
		if r0 < 0:
			r0 = -r0
			x0 = -x0
			y0 = -y0
		return [r0,x0,y0]

def mod(a, m):
	return a%m


def modmul(a, b, m):
	return mod(a*b,m)

def modinv(a, m):
	ls = euclid(a,m)
	if ls[0] != 1:
		print 'modinverr'
		exit(0)
	else:
		return mod(ls[1],m)
		
def moddiv(a, b, m):
	return modmul(a,modinv(b,m),m)

def powermod(a, e, m):
	if e < 0:
		a = modinv(a,m)
		e = -e
	x = 1
	b = a
	while e > 0:
		if e%2 == 1:
			x = modmul(x,b,m)
		b = modmul(b,b,m)
		e /= 2
	return x


def longsqrt(a):
        if a < 0:
                print 'sdfsdf'
                exit()
        else:
                if a <= 1:
                	return a
                s = a
                while s*s > a:
                	s = (s + a/s)/2
        return s

def ElGamalDecrypt(u, v, p, s):
	return modmul(powermod(u,p-1-s,p),v,p)

def chinese(a, b, m, n):
	e = euclid(m, n)
	d = e[0]
	if d != 1:
		print 'zxczxc'
		exit()
	else:
		u = e[1]
		v = e[2]
		return mod(a*n*v+b*m*u, m*n)

def multichinese(am):
	if len(am) == 1:
		return mod(am[0][0], am[0][1])
	am1 = am[1:]
	k = len(am1)
	mm = 1
	for i in range(0, k):
		mm *= am1[i][1]
	x1 = multichinese(am1)
	return chinese(am[0][0], x1, am[0][1], mm)

##### Pohlig-Hellman @ #####

def GetSecret(p, y):
	g = 2
	q = []
	m = p-1
	r = 2
	s = longsqrt(m)
	while r <= s:
		if m % r == 0:	
			e = 0
			while m % r == 0:
				m /= r
				e += 1
			q.append([r,e])
			s = longsqrt(m)
		r += 1
	if m > 1:
		q.append([m,1])

	t0 = time()
	ls = []	
	for re in q:
		r = re[0]
		e = re[1]
		m = p-1
		mm = m/(r**e)
		ymm = powermod(y,mm,p)
		gmm = powermod(g,mm,p)
		gg = powermod(g,m/r,p)
		xr = 0
		for i in range(0,e):
			m /= r
			yy = moddiv(powermod(ymm,m/mm,p),powermod(gmm,(m/mm)*xr,p),p)
			ggj = 1			
			for j in range(0,r):
				if yy == ggj:		
					xr += j * (r**i)
					break
				ggj = modmul(ggj,gg,p)
		ls.append([xr,r**e])

	x = multichinese(ls)
	return x

msgenc = '(16777259,2,8572031) (8528712,11633764);(11912890,16147792);(5329917,4927963);(1816982,6221827);(11081954,14768326);(10573461,10057203);(8305938,8404152);(9931321,16087922);(2450572,14991352);(4516958,8493460);(3195906,6497578)'
pubkey = msgenc.split(' ')[0]
p  = pubkey.split(',')[0][1:]
print "p =", p
msg=msgenc.split(' ')[1]
y=pubkey.split(',')[2][:-1]
print "y =", y
x = GetSecret(int(p),int(y))
print "x =", x
ccs=msg.split(';')
flag = ''
for cc in ccs:
	(c1,c2) = cc.split(',')
	res=ElGamalDecrypt(int(c1[1:]),int(c2[:-1]),int(p),int(x))
	flag = flag + struct.pack('I',res).strip('\0')
print "Flag =",flag

