import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.PrintWriter;
import java.util.TreeMap;
public class E1113
{
    static class QN{
        int index;
        long sum;
        QN(int in,long an){
            index=in;
            sum=an;
        }
    }
    static class SegmentTree{
        long sum,pmin,lazy;
        int st,en;
        boolean rem;
        SegmentTree left,right;
        SegmentTree(int _st,int _en,long _v){
            st=_st;
            en=_en;
            lazy=_v;
            rem=true;
            sum=(en-st+1)*lazy;
            pmin=Math.min(lazy,sum);
        }
        long pmin(){
            return rem?(Math.min(lazy,(en-st+1)*lazy)):(pmin);
        }
        long sum(){
            return rem?((en-st+1)*lazy):(sum);
        }
        void update(int l,int r,long v){
            //completely outside
            if(l>en||r<st)
                return;
            //completely inside
            if(l<=st&&r>=en){
                //update lazy;
                lazy=v;
                rem=true;
                return;
            }
            //partial cover
            lazyPropagate();
            left.update(l, r, v);
            right.update(l, r, v);
            sum=left.sum()+right.sum();
            pmin=Math.min(left.pmin(),left.sum()+right.pmin());
            return;
        }
        void lazyPropagate(){
            if(left==null){
                int mid=(st+en)>>1;
                left=new SegmentTree(st,mid,lazy);
                right=new SegmentTree(mid+1,en,lazy);
            }else if(rem){
                left.lazy=lazy;
                right.lazy=lazy;
                left.rem=true;
                right.rem=true;
            }
            if(rem){
                sum=(en-st+1)*lazy;
                pmin=Math.min(lazy,sum);
            }
            rem=false;
        }
        /**returns least index which has value <= given value**/
        QN query(int l,int r,long v,long su){
            //no cover
            if(st>r||en<l)
                return new QN(-1,0);
            //full cover
            if(l<=st&&en<=r){
                if(su+pmin()<=v)
                    return query2(v,su);
                return new QN(-1,su+sum());
            }
            lazyPropagate();

            QN q1=left.query(l,r,v,su);
            if(q1.index!=-1)
                return q1;
            q1=right.query(l,r,v,q1.sum);
            return q1;
        }
        QN query2(long v,long su){
            if(st==en)
                return new QN(st,su+sum());
            lazyPropagate();
            if(left.pmin()+su<=v)
                return left.query2(v,su);
            else
                return right.query2(v,su+left.sum());

        }

    }
    static class Scanner
    {
        BufferedReader br;
        StringTokenizer tk=new StringTokenizer("");
        public Scanner(InputStream is)
        {
            br=new BufferedReader(new InputStreamReader(is));
        }
        public int nextInt() throws IOException
        {
            if(tk.hasMoreTokens())
                return Integer.parseInt(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextInt();
        }
        public long nextLong() throws IOException
        {
            if(tk.hasMoreTokens())
                return Long.parseLong(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextLong();
        }
        public String next() throws IOException
        {
            if(tk.hasMoreTokens())
                return (tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return next();
        }
        public String nextLine() throws IOException
        {
            tk=new StringTokenizer("");
            return br.readLine();
        }
        public double nextDouble() throws IOException
        {
            if(tk.hasMoreTokens())
                return Double.parseDouble(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextDouble();
        }
        public char nextChar() throws IOException
        {
            if(tk.hasMoreTokens())
                return (tk.nextToken().charAt(0));
            tk=new StringTokenizer(br.readLine());
            return nextChar();
        }
        public int[] nextIntArray(int n) throws IOException
        {
            int a[]=new int[n];
            for(int i=0;i<n;i++)
                a[i]=nextInt();
            return a;
        }
        public long[] nextLongArray(int n) throws IOException
        {
            long a[]=new long[n];
            for(int i=0;i<n;i++)
                a[i]=nextLong();
            return a;
        }
        public int[] nextIntArrayOneBased(int n) throws IOException
        {
            int a[]=new int[n+1];
            for(int i=1;i<=n;i++)
                a[i]=nextInt();
            return a;
        }
        public long[] nextLongArrayOneBased(int n) throws IOException
        {
            long a[]=new long[n+1];
            for(int i=1;i<=n;i++)
                a[i]=nextLong();
            return a;
        }

    }

    public static void main(String args[]) throws IOException
    {
        Scanner in=new Scanner(System.in);
        PrintWriter out=new PrintWriter(System.out);
        SegmentTree st=new SegmentTree(1,1000000000,0);
        int q=in.nextInt();
        TreeMap<Integer,Integer> mp=new TreeMap<>();
        mp.put(0,0);
        mp.put(1000000001,0);
        while(q--!=0){
            int tp=in.nextInt();
            switch(tp){
                case 1:
                    int tm=in.nextInt();
                    int vl=in.nextInt();
                    int nxt=mp.higherKey(tm)-1;
                    st.update(tm, nxt, vl);
                    mp.put(tm,vl);
                    break;
                case 2:
                    int tc=in.nextInt();
                    int vp=mp.lowerEntry(tc).getValue();
                    int net=mp.higherKey(tc)-1;
                    st.update(tc, net, vp);
                    mp.remove(tc);
                    break;
                case 3:
                    int l=in.nextInt();
                    int lc=l;
                    l=mp.ceilingKey(l);
                    int r=in.nextInt();
                    int v=in.nextInt();
                    if(v==0){
                        out.println(lc);
                        continue;
                    }
                    if(l>=r){
                        out.println(-1);
                        continue;
                    }
                    QN aa=st.query(l, r-1, -v, 0);
                    if(aa.index==-1)
                        out.println(-1);
                    else{
                        int spd=mp.floorEntry(aa.index).getValue();
                        double remv=-(v+(aa.sum-spd));
                        double anss=aa.index;
                        anss+=remv/spd;
                        out.println(anss);

                    }

            }

        }
        out.close();
    }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
import java.io.PrintWriter;
import java.util.TreeMap;
public class E1113
{
    static class QN{
        int index;
        long sum;
        QN(int in,long an){
            index=in;
            sum=an;
        }
    }
    static class SegmentTree{
        long sum,pmin,lazy;
        int st,en;
        boolean rem;
        SegmentTree left,right;
        SegmentTree(int _st,int _en,long _v){
            st=_st;
            en=_en;
            lazy=_v;
            rem=true;
            sum=(en-st+1)*lazy;
            pmin=Math.min(lazy,sum);
        }
        long pmin(){
            return rem?(Math.min(lazy,(en-st+1)*lazy)):(pmin);
        }
        long sum(){
            return rem?((en-st+1)*lazy):(sum);
        }
        void update(int l,int r,long v){
            //completely outside
            if(l>en||r<st)
                return;
            //completely inside
            if(l<=st&&r>=en){
                //update lazy;
                lazy=v;
                rem=true;
                return;
            }
            //partial cover
            lazyPropagate();
            left.update(l, r, v);
            right.update(l, r, v);
            sum=left.sum()+right.sum();
            pmin=Math.min(left.pmin(),left.sum()+right.pmin());
            return;
        }
        void lazyPropagate(){
            if(left==null){
                int mid=(st+en)/2;
                left=new SegmentTree(st,mid,lazy);
                right=new SegmentTree(mid+1,en,lazy);
            }else if(rem){
                left.lazy=lazy;
                right.lazy=lazy;
                left.rem=true;
                right.rem=true;
            }
            if(rem){
                sum=(en-st+1)*lazy;
                pmin=Math.min(lazy,sum);
            }
            rem=false;
        }
        /**returns least index which has value <= given value**/
        QN query(int l,int r,long v,long su){
            //no cover
            if(st>r||en<l)
                return new QN(-1,0);
            //full cover
            if(l<=st&&en<=r){
                if(su+pmin()<=v)
                    return query2(v,su);
                return new QN(-1,su+sum());
            }
            lazyPropagate();

            QN q1=left.query(l,r,v,su);
            if(q1.index!=-1)
                return q1;
            q1=right.query(l,r,v,q1.sum);
            return q1;
        }
        QN query2(long v,long su){
            if(st==en)
                return new QN(st,su+sum());
            lazyPropagate();
            if(left.pmin()+su<=v)
                return left.query2(v,su);
            else
                return right.query2(v,su+left.sum());

        }

    }
    static class Scanner
    {
        BufferedReader br;
        StringTokenizer tk=new StringTokenizer("");
        public Scanner(InputStream is)
        {
            br=new BufferedReader(new InputStreamReader(is));
        }
        public int nextInt() throws IOException
        {
            if(tk.hasMoreTokens())
                return Integer.parseInt(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextInt();
        }
        public long nextLong() throws IOException
        {
            if(tk.hasMoreTokens())
                return Long.parseLong(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextLong();
        }
        public String next() throws IOException
        {
            if(tk.hasMoreTokens())
                return (tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return next();
        }
        public String nextLine() throws IOException
        {
            tk=new StringTokenizer("");
            return br.readLine();
        }
        public double nextDouble() throws IOException
        {
            if(tk.hasMoreTokens())
                return Double.parseDouble(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextDouble();
        }
        public char nextChar() throws IOException
        {
            if(tk.hasMoreTokens())
                return (tk.nextToken().charAt(0));
            tk=new StringTokenizer(br.readLine());
            return nextChar();
        }
        public int[] nextIntArray(int n) throws IOException
        {
            int a[]=new int[n];
            for(int i=0;i<n;i++)
                a[i]=nextInt();
            return a;
        }
        public long[] nextLongArray(int n) throws IOException
        {
            long a[]=new long[n];
            for(int i=0;i<n;i++)
                a[i]=nextLong();
            return a;
        }
        public int[] nextIntArrayOneBased(int n) throws IOException
        {
            int a[]=new int[n+1];
            for(int i=1;i<=n;i++)
                a[i]=nextInt();
            return a;
        }
        public long[] nextLongArrayOneBased(int n) throws IOException
        {
            long a[]=new long[n+1];
            for(int i=1;i<=n;i++)
                a[i]=nextLong();
            return a;
        }

    }

    public static void main(String args[]) throws IOException
    {
        Scanner in=new Scanner(System.in);
        PrintWriter out=new PrintWriter(System.out);
        SegmentTree st=new SegmentTree(1,1000000000,0);
        int q=in.nextInt();
        TreeMap<Integer,Integer> mp=new TreeMap<>();
        mp.put(0,0);
        mp.put(1000000001,0);
        while(q--!=0){
            int tp=in.nextInt();
            switch(tp){
                case 1:
                    int tm=in.nextInt();
                    int vl=in.nextInt();
                    int nxt=mp.higherKey(tm)-1;
                    st.update(tm, nxt, vl);
                    mp.put(tm,vl);
                    break;
                case 2:
                    int tc=in.nextInt();
                    int vp=mp.lowerEntry(tc).getValue();
                    int net=mp.higherKey(tc)-1;
                    st.update(tc, net, vp);
                    mp.remove(tc);
                    break;
                case 3:
                    int l=in.nextInt();
                    int lc=l;
                    l=mp.ceilingKey(l);
                    int r=in.nextInt();
                    int v=in.nextInt();
                    if(v==0){
                        out.println(lc);
                        continue;
                    }
                    if(l>=r){
                        out.println(-1);
                        continue;
                    }
                    QN aa=st.query(l, r-1, -v, 0);
                    if(aa.index==-1)
                        out.println(-1);
                    else{
                        int spd=mp.floorEntry(aa.index).getValue();
                        double remv=-(v+(aa.sum-spd));
                        double anss=aa.index;
                        anss+=remv/spd;
                        out.println(anss);

                    }

            }

        }
        out.close();
    }

}


//package educational.round049;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class G2 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";
	// 11 2 3 3 3 2 2 3

	void solve()
	{
		long m = nl(), x = nl();
		int[] primes = sieveEratosthenes(10000000);
		long[] ds = enumDivisors(m, primes);
		Arrays.sort(ds);
		long[] gf = factor(m, primes);

		long ans = 0;
		for(long d : ds){
			long t = totient(d, gf);
			long[] f = factor(t, primes);
			long P = period(x%d, d, f, t);
			assert t % P == 0;
			ans += t / P;
//			tr(d, t, period(x%d, d, f, t));
		}
		out.println(ans);
	}

	long period(long x, long d, long[] f, long t)
	{
		if(d > 1e9){
			// x^k=1 (mod d)
			assert powSafe(x, t, d) == 1%d;
			for(long e : f){
				while(t % e == 0 && powSafe(x, t/e, d) == 1%d){
					t /= e;
				}
			}
		}else{
			assert pow(x, t, d) == 1%d;
			for(long e : f){
				while(t % e == 0 && pow(x, t/e, d) == 1%d){
					t /= e;
				}
			}
		}
		return t;
	}

	public static long pow(long a, long n, long mod) {
		//		a %= mod;
		long ret = 1;
		int x = 63 - Long.numberOfLeadingZeros(n);
		for (; x >= 0; x--) {
			ret = ret * ret % mod;
			if (n << 63 - x < 0)
				ret = ret * a % mod;
		}
		return ret;
	}

	public static long powSafe(long a, long n, long mod)
	{
//		a %= mod;
		long ret = 1; // 1%mod if mod=1,n=0
		int x = 63-Long.numberOfLeadingZeros(n);
		for(;x >= 0;x--){
			ret = mulEx(ret, ret, mod);
			if(n<<~x<0)ret = mulEx(ret, a, mod);
		}
		return ret;
	}

	public static long mulEx(long a, long b, long mod)
	{
		if(a >= mod || a < 0)a %= mod;
		if(a < 0)a += mod;
		if(b >= mod || b < 0)b %= mod;
		if(b < 0)b += mod;

		long ret = 0;
		int x = 63-Long.numberOfLeadingZeros(b);
		for(;x >= 0;x--){
			ret += ret;
			if(Long.compareUnsigned(ret, mod) >= 0)ret -= mod;
			if(b<<~x<0){
				ret += a;
				if(Long.compareUnsigned(ret, mod) >= 0)ret -= mod;
			}
		}
		return ret;
	}

	public static long totient(long n, long[] primes)
	{
		long ret = n;
		for(long p : primes){
			if((long)p * p > n)break;
			if(n % p == 0){
				ret /= p;
				ret *= p - 1;
			}
			while(n % p == 0)n /= p;
		}
		if(n != 1){
			ret /= n;
			ret *= n - 1;
		}
		return ret;
	}

	public static long[] factor(long n, int[] primes)
	{
		long[] ret = new long[20];
		int rp = 0;
		for(int p : primes){
			if((long)p * p > n)break;
			int i;
			for(i = 0;n % p == 0;n /= p, i++);
			if(i > 0){
				ret[rp] = p;
				rp++;
			}
		}
		if(n != 1){
			ret[rp] = n;
			rp++;
		}
		return Arrays.copyOf(ret, rp);
	}

	public static long[] enumDivisors(long n, int[] primes)
	{
		int m = 1;
		long[] divs = {1L};
		int t = 1;
		long u = n;
		for(int p : primes){
			if((long)p*p > u)break;
			int e = 0;
			while(u % p == 0){
				u /= p;
				e++;
			}
			if(e > 0){
				divs = Arrays.copyOf(divs, t*(e+1));
				for(int q = t-1;q >= 0;q--){
					long b = divs[q];
					for(int k = 0;k < e;k++){
						b *= p;
//						if((long)b*b <= n)divs[t++] = b;
						divs[t++] = b;
					}
				}
				m *= e+1;
			}
		}
		if(u > 1){
			long p = u;
			int e = 1;
			divs = Arrays.copyOf(divs, t*(e+1));
			for(int q = t-1;q >= 0;q--){
				long b = divs[q];
				for(int k = 0;k < e;k++){
					b *= p;
//					if((long)b*b <= n)divs[t++] = b;
					divs[t++] = b;
				}
			}
			m *= e+1;
		}

		return Arrays.copyOf(divs, t);
	}

	public static int[][] factor(int n, int[] primes)
	{
		int[][] ret = new int[9][2];
		int rp = 0;
		for(int p : primes){
			if(p * p > n)break;
			int i;
			for(i = 0;n % p == 0;n /= p, i++);
			if(i > 0){
				ret[rp][0] = p;
				ret[rp][1] = i;
				rp++;
			}
		}
		if(n != 1){
			ret[rp][0] = n;
			ret[rp][1] = 1;
			rp++;
		}
		return Arrays.copyOf(ret, rp);
	}

	public static int gcd(int a, int b) {
		while (b > 0) {
			int c = a;
			a = b;
			b = c % b;
		}
		return a;
	}

	public static int[] sieveEratosthenes(int n) {
		if (n <= 32) {
			int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
			for (int i = 0; i < primes.length; i++) {
				if (n < primes[i]) {
					return Arrays.copyOf(primes, i);
				}
			}
			return primes;
		}

		int u = n + 32;
		double lu = Math.log(u);
		int[] ret = new int[(int) (u / lu + u / lu / lu * 1.5)];
		ret[0] = 2;
		int pos = 1;

		int[] isnp = new int[(n + 1) / 32 / 2 + 1];
		int sup = (n + 1) / 32 / 2 + 1;

		int[] tprimes = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
		for (int tp : tprimes) {
			ret[pos++] = tp;
			int[] ptn = new int[tp];
			for (int i = (tp - 3) / 2; i < tp << 5; i += tp)
				ptn[i >> 5] |= 1 << (i & 31);
			for (int j = 0; j < sup; j += tp) {
				for (int i = 0; i < tp && i + j < sup; i++) {
					isnp[j + i] |= ptn[i];
				}
			}
		}

		// 3,5,7
		// 2x+3=n
		int[] magic = { 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, 31, 22, 28, 18, 26, 10, 7, 12, 21, 17,
				9, 6, 16, 5, 15, 14 };
		int h = n / 2;
		for (int i = 0; i < sup; i++) {
			for (int j = ~isnp[i]; j != 0; j &= j - 1) {
				int pp = i << 5 | magic[(j & -j) * 0x076be629 >>> 27];
				int p = 2 * pp + 3;
				if (p > n)
					break;
				ret[pos++] = p;
				if ((long) p * p > n)
					continue;
				for (int q = (p * p - 3) / 2; q <= h; q += p)
					isnp[q >> 5] |= 1 << q;
			}
		}

		return Arrays.copyOf(ret, pos);
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new G2().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.io.IOException;
import java.util.Random;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            GXMouseInTheCampus solver = new GXMouseInTheCampus();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class GXMouseInTheCampus {
        LongHashMap mu = new LongHashMap(100000, false);
        LongHashMap euler = new LongHashMap(100000, false);
        long[] primes;

        {
            mu.put(1, 1);
            euler.put(1, 1);
        }

        public long oneOfPrimeFactor(long x) {
            for (long p : primes) {
                if (x % p == 0) {
                    return p;
                }
            }
            return x;
        }

        public void populate(long x) {
            long factor = oneOfPrimeFactor(x);
            long cnt = 0;
            long y = x;
            while (y % factor == 0) {
                cnt++;
                y /= factor;
            }
            if (cnt > 1) {
                mu.put(x, 0);
            } else {
                mu.put(x, -mu(y));
            }
            euler.put(x, euler(y) * (x / y - x / y / factor));
        }

        public long mu(long x) {
            long ans = mu.getOrDefault(x, -1);
            if (ans == -1) {
                populate(x);
                ans = mu.get(x);
            }
            return ans;
        }

        public long euler(long x) {
            long ans = euler.getOrDefault(x, -1);
            if (ans == -1) {
                populate(x);
                ans = euler.get(x);
            }
            return ans;
        }

        public void solve(int testNumber, FastInput in, FastOutput out) {
            long m = in.readLong();
            long x = in.readLong();

            primes = Factorization.factorizeNumberPrime(m).toArray();
            LongList allFactorOfM = new LongList(20000);
            LongList tmpList = new LongList(20000);
            LongList allPossiblePrimeFactor = new LongList();
            for (long p : primes) {
                allPossiblePrimeFactor.add(p);
                allPossiblePrimeFactor.addAll(Factorization.factorizeNumberPrime(p - 1));
            }
            allPossiblePrimeFactor.unique();

            collect(allFactorOfM, m, 0);
            LongPower power = new LongPower(ILongModular.getInstance(m));

            long total = 1;
            for (int i = 0; i < allFactorOfM.size(); i++) {
                long g = allFactorOfM.get(i);
                if (g == m) {
                    continue;
                }
                long mg = m / g;
                tmpList.clear();
                collect(tmpList, mg, 0);
                long cnt = 0;
                for (int j = tmpList.size() - 1; j >= 0; j--) {
                    long t = tmpList.get(j);
                    cnt += mu(t) * ((m - 1) / (t * g));
                }

                tmpList.clear();
                long euler = euler(mg);
                LongList primeFactors = tmpList;
                for (int j = 0; j < allPossiblePrimeFactor.size(); j++) {
                    long p = allPossiblePrimeFactor.get(j);
                    if (euler % p == 0) {
                        primeFactors.add(p);
                    }
                }

                long n = euler;
                for (int j = 0; j < primeFactors.size(); j++) {
                    long p = primeFactors.get(j);
                    while (n % p == 0 && power.pow(x, n / p) % mg == 1) {
                        n /= p;
                    }
                }

                if (cnt % n != 0) {
                    throw new IllegalStateException();
                }
                total += cnt / n;
            }

            out.println(total);
        }

        public void collect(LongList list, long x, int i) {
            if (i == primes.length) {
                list.add(x);
                return;
            }
            collect(list, x, i + 1);
            while (x % primes[i] == 0) {
                x /= primes[i];
                collect(list, x, i + 1);
            }
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static long round(double x) {
            if (x >= 0) {
                return (long) (x + 0.5);
            } else {
                return (long) (x - 0.5);
            }
        }

        public static long mod(long x, long mod) {
            x %= mod;
            if (x < 0) {
                x += mod;
            }
            return x;
        }

        public static long mulMod(long a, long b, long mod) {
            long k = DigitUtils.round((double) a / mod * b);
            return DigitUtils.mod(a * b - k * mod, mod);
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(long c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class LongPower {
        final ILongModular modular;

        public LongPower(ILongModular modular) {
            this.modular = modular;
        }

        public long pow(long x, long n) {
            if (n == 0) {
                return 1;
            }
            long r = pow(x, n >> 1);
            r = modular.mul(r, r);
            if ((n & 1) == 1) {
                r = modular.mul(r, x);
            }
            return r;
        }

    }

    static class Factorization {
        public static LongList factorizeNumberPrime(long x) {
            LongList ans = new LongList();
            for (long i = 2; i * i <= x; i++) {
                if (x % i != 0) {
                    continue;
                }
                ans.add(i);
                while (x % i == 0) {
                    x /= i;
                }
            }
            if (x > 1) {
                ans.add(x);
            }
            return ans;
        }

    }

    static class LongHashMap {
        private int[] slot;
        private int[] next;
        private long[] keys;
        private long[] values;
        private int alloc;
        private boolean[] removed;
        private int mask;
        private int size;
        private boolean rehash;

        public LongHashMap(int cap, boolean rehash) {
            this.mask = (1 << (32 - Integer.numberOfLeadingZeros(cap - 1))) - 1;
            slot = new int[mask + 1];
            next = new int[cap + 1];
            keys = new long[cap + 1];
            values = new long[cap + 1];
            removed = new boolean[cap + 1];
            this.rehash = rehash;
        }

        private void doubleCapacity() {
            int newSize = Math.max(next.length + 10, next.length * 2);
            next = Arrays.copyOf(next, newSize);
            keys = Arrays.copyOf(keys, newSize);
            values = Arrays.copyOf(values, newSize);
            removed = Arrays.copyOf(removed, newSize);
        }

        public void alloc() {
            alloc++;
            if (alloc >= next.length) {
                doubleCapacity();
            }
            next[alloc] = 0;
            removed[alloc] = false;
            size++;
        }

        private void rehash() {
            int[] newSlots = new int[Math.max(16, slot.length * 2)];
            int newMask = newSlots.length - 1;
            for (int i = 0; i < slot.length; i++) {
                if (slot[i] == 0) {
                    continue;
                }
                int head = slot[i];
                while (head != 0) {
                    int n = next[head];
                    int s = hash(keys[head]) & newMask;
                    next[head] = newSlots[s];
                    newSlots[s] = head;
                    head = n;
                }
            }
            this.slot = newSlots;
            this.mask = newMask;
        }

        private int hash(long x) {
            int h = Long.hashCode(x);
            return h ^ (h >>> 16);
        }

        public void put(long x, long y) {
            put(x, y, true);
        }

        public void put(long x, long y, boolean cover) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                alloc();
                slot[s] = alloc;
                keys[alloc] = x;
                values[alloc] = y;
            } else {
                int index = findIndexOrLastEntry(s, x);
                if (keys[index] != x) {
                    alloc();
                    next[index] = alloc;
                    keys[alloc] = x;
                    values[alloc] = y;
                } else if (cover) {
                    values[index] = y;
                }
            }
            if (rehash && size >= slot.length) {
                rehash();
            }
        }

        public long getOrDefault(long x, long def) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                return def;
            }
            int index = findIndexOrLastEntry(s, x);
            return keys[index] == x ? values[index] : def;
        }

        public long get(long x) {
            return getOrDefault(x, 0);
        }

        private int findIndexOrLastEntry(int s, long x) {
            int iter = slot[s];
            while (keys[iter] != x) {
                if (next[iter] != 0) {
                    iter = next[iter];
                } else {
                    return iter;
                }
            }
            return iter;
        }

        public LongEntryIterator iterator() {
            return new LongEntryIterator() {
                int index = 1;
                int readIndex = -1;

                public boolean hasNext() {
                    while (index <= alloc && removed[index]) {
                        index++;
                    }
                    return index <= alloc;
                }

                public long getEntryKey() {
                    return keys[readIndex];
                }

                public long getEntryValue() {
                    return values[readIndex];
                }

                public void next() {
                    if (!hasNext()) {
                        throw new IllegalStateException();
                    }
                    readIndex = index;
                    index++;
                }
            };
        }

        public String toString() {
            LongEntryIterator iterator = iterator();
            StringBuilder builder = new StringBuilder("{");
            while (iterator.hasNext()) {
                iterator.next();
                builder.append(iterator.getEntryKey()).append("->").append(iterator.getEntryValue()).append(',');
            }
            if (builder.charAt(builder.length() - 1) == ',') {
                builder.setLength(builder.length() - 1);
            }
            builder.append('}');
            return builder.toString();
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public long readLong() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            long val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static interface LongEntryIterator {
        boolean hasNext();

        void next();

        long getEntryKey();

        long getEntryValue();

    }

    static class LongModular implements ILongModular {
        final long m;

        public LongModular(long m) {
            this.m = m;
        }

        public long mul(long a, long b) {
            return b == 0 ? 0 : ((mul(a, b >> 1) << 1) % m + a * (b & 1)) % m;
        }

    }

    static class LongModularDanger implements ILongModular {
        final long m;

        public LongModularDanger(long m) {
            this.m = m;
        }

        public long mul(long a, long b) {
            return DigitUtils.mulMod(a, b, m);
        }

    }

    static class LongList implements Cloneable {
        private int size;
        private int cap;
        private long[] data;
        private static final long[] EMPTY = new long[0];

        public LongList(int cap) {
            this.cap = cap;
            if (cap == 0) {
                data = EMPTY;
            } else {
                data = new long[cap];
            }
        }

        public LongList(LongList list) {
            this.size = list.size;
            this.cap = list.cap;
            this.data = Arrays.copyOf(list.data, size);
        }

        public LongList() {
            this(0);
        }

        public void ensureSpace(int req) {
            if (req > cap) {
                while (cap < req) {
                    cap = Math.max(cap + 10, 2 * cap);
                }
                data = Arrays.copyOf(data, cap);
            }
        }

        private void checkRange(int i) {
            if (i < 0 || i >= size) {
                throw new ArrayIndexOutOfBoundsException();
            }
        }

        public long get(int i) {
            checkRange(i);
            return data[i];
        }

        public void add(long x) {
            ensureSpace(size + 1);
            data[size++] = x;
        }

        public void addAll(long[] x, int offset, int len) {
            ensureSpace(size + len);
            System.arraycopy(x, offset, data, size, len);
            size += len;
        }

        public void addAll(LongList list) {
            addAll(list.data, 0, list.size);
        }

        public void sort() {
            if (size <= 1) {
                return;
            }
            Randomized.shuffle(data, 0, size);
            Arrays.sort(data, 0, size);
        }

        public void unique() {
            if (size <= 1) {
                return;
            }

            sort();
            int wpos = 1;
            for (int i = 1; i < size; i++) {
                if (data[i] != data[wpos - 1]) {
                    data[wpos++] = data[i];
                }
            }
            size = wpos;
        }

        public int size() {
            return size;
        }

        public long[] toArray() {
            return Arrays.copyOf(data, size);
        }

        public void clear() {
            size = 0;
        }

        public String toString() {
            return Arrays.toString(toArray());
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof LongList)) {
                return false;
            }
            LongList other = (LongList) obj;
            return SequenceUtils.equal(data, 0, size - 1, other.data, 0, other.size - 1);
        }

        public int hashCode() {
            int h = 1;
            for (int i = 0; i < size; i++) {
                h = h * 31 + Long.hashCode(data[i]);
            }
            return h;
        }

        public LongList clone() {
            LongList ans = new LongList();
            ans.addAll(this);
            return ans;
        }

    }

    static interface ILongModular {
        long mul(long a, long b);

        static ILongModular getInstance(long mod) {
            //return new LongModularDanger(mod);
            return mod <= (1L << 54) ? new LongModularDanger(mod) : new LongModular(mod);
        }

    }

    static class SequenceUtils {
        public static boolean equal(long[] a, int al, int ar, long[] b, int bl, int br) {
            if ((ar - al) != (br - bl)) {
                return false;
            }
            for (int i = al, j = bl; i <= ar; i++, j++) {
                if (a[i] != b[j]) {
                    return false;
                }
            }
            return true;
        }

    }

    static class Randomized {
        private static Random random = new Random(0);

        public static void shuffle(long[] data, int from, int to) {
            to--;
            for (int i = from; i <= to; i++) {
                int s = nextInt(i, to);
                long tmp = data[i];
                data[i] = data[s];
                data[s] = tmp;
            }
        }

        public static int nextInt(int l, int r) {
            return random.nextInt(r - l + 1) + l;
        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 27);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            GXMouseInTheCampus solver = new GXMouseInTheCampus();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class GXMouseInTheCampus {
        LongHashMap mu = new LongHashMap(100000, false);
        LongHashMap euler = new LongHashMap(100000, false);
        long[] primes;

        {
            mu.put(1, 1);
            euler.put(1, 1);
        }

        public long oneOfPrimeFactor(long x) {
            for (long p : primes) {
                if (x % p == 0) {
                    return p;
                }
            }
            return x;
        }

        public void populate(long x) {
            long factor = oneOfPrimeFactor(x);
            long cnt = 0;
            long y = x;
            while (y % factor == 0) {
                cnt++;
                y /= factor;
            }
            if (cnt > 1) {
                mu.put(x, 0);
            } else {
                mu.put(x, -mu(y));
            }
            euler.put(x, euler(y) * (x / y - x / y / factor));
        }

        public long mu(long x) {
            long ans = mu.getOrDefault(x, -1);
            if (ans == -1) {
                populate(x);
                ans = mu.get(x);
            }
            return ans;
        }

        public long euler(long x) {
            long ans = euler.getOrDefault(x, -1);
            if (ans == -1) {
                populate(x);
                ans = euler.get(x);
            }
            return ans;
        }

        public void solve(int testNumber, FastInput in, FastOutput out) {
            long m = in.readLong();
            long x = in.readLong();

            primes = Factorization.factorizeNumberPrime(m).toArray();
            LongList allFactorOfM = new LongList(20000);
            LongList tmpList = new LongList(20000);
            collect(allFactorOfM, m, 0);
            LongPower power = new LongPower(ILongModular.getInstance(m));

            long total = 1;
            for (int i = 0; i < allFactorOfM.size(); i++) {
                long g = allFactorOfM.get(i);
                if (g == m) {
                    continue;
                }
                long mg = m / g;
                tmpList.clear();
                collect(tmpList, mg, 0);
                long cnt = 0;
                for (int j = tmpList.size() - 1; j >= 0; j--) {
                    long t = tmpList.get(j);
                    cnt += mu(t) * ((m - 1) / (t * g));
                }

                tmpList.clear();
                long euler = euler(mg);
                LongList primeFactors = Factorization.factorizeNumberPrime(euler);

                long n = euler;

                for (int j = 0; j < primeFactors.size(); j++) {
                    long p = primeFactors.get(j);
                    while (n % p == 0 && power.pow(x, n / p) % mg == 1) {
                        n /= p;
                    }
                }

                if (cnt % n != 0) {
                    throw new IllegalStateException();
                }
                total += cnt / n;
            }

            out.println(total);
        }

        public void collect(LongList list, long x, int i) {
            if (i == primes.length) {
                list.add(x);
                return;
            }
            collect(list, x, i + 1);
            while (x % primes[i] == 0) {
                x /= primes[i];
                collect(list, x, i + 1);
            }
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static long round(double x) {
            if (x >= 0) {
                return (long) (x + 0.5);
            } else {
                return (long) (x - 0.5);
            }
        }

        public static long mod(long x, long mod) {
            x %= mod;
            if (x < 0) {
                x += mod;
            }
            return x;
        }

        public static long mulMod(long a, long b, long mod) {
            long k = DigitUtils.round((double) a / mod * b);
            return DigitUtils.mod(a * b - k * mod, mod);
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(long c) {
            cache.append(c);
            println();
            return this;
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class LongPower {
        final ILongModular modular;

        public LongPower(ILongModular modular) {
            this.modular = modular;
        }

        public long pow(long x, long n) {
            if (n == 0) {
                return 1;
            }
            long r = pow(x, n >> 1);
            r = modular.mul(r, r);
            if ((n & 1) == 1) {
                r = modular.mul(r, x);
            }
            return r;
        }

    }

    static class Factorization {
        public static LongList factorizeNumberPrime(long x) {
            LongList ans = new LongList();
            for (long i = 2; i * i <= x; i++) {
                if (x % i != 0) {
                    continue;
                }
                ans.add(i);
                while (x % i == 0) {
                    x /= i;
                }
            }
            if (x > 1) {
                ans.add(x);
            }
            return ans;
        }

    }

    static class LongHashMap {
        private int[] slot;
        private int[] next;
        private long[] keys;
        private long[] values;
        private int alloc;
        private boolean[] removed;
        private int mask;
        private int size;
        private boolean rehash;

        public LongHashMap(int cap, boolean rehash) {
            this.mask = (1 << (32 - Integer.numberOfLeadingZeros(cap - 1))) - 1;
            slot = new int[mask + 1];
            next = new int[cap + 1];
            keys = new long[cap + 1];
            values = new long[cap + 1];
            removed = new boolean[cap + 1];
            this.rehash = rehash;
        }

        private void doubleCapacity() {
            int newSize = Math.max(next.length + 10, next.length * 2);
            next = Arrays.copyOf(next, newSize);
            keys = Arrays.copyOf(keys, newSize);
            values = Arrays.copyOf(values, newSize);
            removed = Arrays.copyOf(removed, newSize);
        }

        public void alloc() {
            alloc++;
            if (alloc >= next.length) {
                doubleCapacity();
            }
            next[alloc] = 0;
            removed[alloc] = false;
            size++;
        }

        private void rehash() {
            int[] newSlots = new int[Math.max(16, slot.length * 2)];
            int newMask = newSlots.length - 1;
            for (int i = 0; i < slot.length; i++) {
                if (slot[i] == 0) {
                    continue;
                }
                int head = slot[i];
                while (head != 0) {
                    int n = next[head];
                    int s = hash(keys[head]) & newMask;
                    next[head] = newSlots[s];
                    newSlots[s] = head;
                    head = n;
                }
            }
            this.slot = newSlots;
            this.mask = newMask;
        }

        private int hash(long x) {
            int h = Long.hashCode(x);
            return h ^ (h >>> 16);
        }

        public void put(long x, long y) {
            put(x, y, true);
        }

        public void put(long x, long y, boolean cover) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                alloc();
                slot[s] = alloc;
                keys[alloc] = x;
                values[alloc] = y;
            } else {
                int index = findIndexOrLastEntry(s, x);
                if (keys[index] != x) {
                    alloc();
                    next[index] = alloc;
                    keys[alloc] = x;
                    values[alloc] = y;
                } else if (cover) {
                    values[index] = y;
                }
            }
            if (rehash && size >= slot.length) {
                rehash();
            }
        }

        public long getOrDefault(long x, long def) {
            int h = hash(x);
            int s = h & mask;
            if (slot[s] == 0) {
                return def;
            }
            int index = findIndexOrLastEntry(s, x);
            return keys[index] == x ? values[index] : def;
        }

        public long get(long x) {
            return getOrDefault(x, 0);
        }

        private int findIndexOrLastEntry(int s, long x) {
            int iter = slot[s];
            while (keys[iter] != x) {
                if (next[iter] != 0) {
                    iter = next[iter];
                } else {
                    return iter;
                }
            }
            return iter;
        }

        public LongEntryIterator iterator() {
            return new LongEntryIterator() {
                int index = 1;
                int readIndex = -1;

                public boolean hasNext() {
                    while (index <= alloc && removed[index]) {
                        index++;
                    }
                    return index <= alloc;
                }

                public long getEntryKey() {
                    return keys[readIndex];
                }

                public long getEntryValue() {
                    return values[readIndex];
                }

                public void next() {
                    if (!hasNext()) {
                        throw new IllegalStateException();
                    }
                    readIndex = index;
                    index++;
                }
            };
        }

        public String toString() {
            LongEntryIterator iterator = iterator();
            StringBuilder builder = new StringBuilder("{");
            while (iterator.hasNext()) {
                iterator.next();
                builder.append(iterator.getEntryKey()).append("->").append(iterator.getEntryValue()).append(',');
            }
            if (builder.charAt(builder.length() - 1) == ',') {
                builder.setLength(builder.length() - 1);
            }
            builder.append('}');
            return builder.toString();
        }

    }

    static class SequenceUtils {
        public static boolean equal(long[] a, int al, int ar, long[] b, int bl, int br) {
            if ((ar - al) != (br - bl)) {
                return false;
            }
            for (int i = al, j = bl; i <= ar; i++, j++) {
                if (a[i] != b[j]) {
                    return false;
                }
            }
            return true;
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public long readLong() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            long val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class LongModular implements ILongModular {
        final long m;

        public LongModular(long m) {
            this.m = m;
        }

        public long mul(long a, long b) {
            return b == 0 ? 0 : ((mul(a, b >> 1) << 1) % m + a * (b & 1)) % m;
        }

    }

    static class LongModularDanger implements ILongModular {
        final long m;

        public LongModularDanger(long m) {
            this.m = m;
        }

        public long mul(long a, long b) {
            return DigitUtils.mulMod(a, b, m);
        }

    }

    static class LongList implements Cloneable {
        private int size;
        private int cap;
        private long[] data;
        private static final long[] EMPTY = new long[0];

        public LongList(int cap) {
            this.cap = cap;
            if (cap == 0) {
                data = EMPTY;
            } else {
                data = new long[cap];
            }
        }

        public LongList(LongList list) {
            this.size = list.size;
            this.cap = list.cap;
            this.data = Arrays.copyOf(list.data, size);
        }

        public LongList() {
            this(0);
        }

        public void ensureSpace(int req) {
            if (req > cap) {
                while (cap < req) {
                    cap = Math.max(cap + 10, 2 * cap);
                }
                data = Arrays.copyOf(data, cap);
            }
        }

        private void checkRange(int i) {
            if (i < 0 || i >= size) {
                throw new ArrayIndexOutOfBoundsException();
            }
        }

        public long get(int i) {
            checkRange(i);
            return data[i];
        }

        public void add(long x) {
            ensureSpace(size + 1);
            data[size++] = x;
        }

        public void addAll(long[] x, int offset, int len) {
            ensureSpace(size + len);
            System.arraycopy(x, offset, data, size, len);
            size += len;
        }

        public void addAll(LongList list) {
            addAll(list.data, 0, list.size);
        }

        public int size() {
            return size;
        }

        public long[] toArray() {
            return Arrays.copyOf(data, size);
        }

        public void clear() {
            size = 0;
        }

        public String toString() {
            return Arrays.toString(toArray());
        }

        public boolean equals(Object obj) {
            if (!(obj instanceof LongList)) {
                return false;
            }
            LongList other = (LongList) obj;
            return SequenceUtils.equal(data, 0, size - 1, other.data, 0, other.size - 1);
        }

        public int hashCode() {
            int h = 1;
            for (int i = 0; i < size; i++) {
                h = h * 31 + Long.hashCode(data[i]);
            }
            return h;
        }

        public LongList clone() {
            LongList ans = new LongList();
            ans.addAll(this);
            return ans;
        }

    }

    static interface LongEntryIterator {
        boolean hasNext();

        void next();

        long getEntryKey();

        long getEntryValue();

    }

    static interface ILongModular {
        long mul(long a, long b);

        static ILongModular getInstance(long mod) {
            //return new LongModularDanger(mod);
            return mod <= (1L << 54) ? new LongModularDanger(mod) : new LongModular(mod);
        }

    }
}


import java.io.*;
import java.util.*;

public class Codeforces830D {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int N = 1000000007;
		int n = Integer.parseInt(st.nextToken());
		int[][] dynamic = new int[n+1][n+1];
		dynamic[1][0] = 1;
		dynamic[1][1] = 1;
		for (int i = 2; i <= n; i++) {
			dynamic[1][i] = 0;
		}
		for (int i = 2; i <= n; i++) {
			for (int r = 0; r <= n+1-i; r++) {
				for (int k = 0; k <= r; k++) {
					dynamic[i][r] = (int) (((long) dynamic[i][r] + (long) dynamic[i-1][k] * (long) dynamic[i-1][r-k])%N);
				}
				for (int k = 0; k < r; k++) {
					dynamic[i][r] = (int) (((long) dynamic[i][r] + (long) dynamic[i-1][k] * (long) dynamic[i-1][r-k-1])%N);
				}
				for (int k = 1; k <= r; k++) {

					dynamic[i][r] = (int) (((long) dynamic[i][r] + ((long) (4*k) * (((long) dynamic[i-1][k] * (long) dynamic[i-1][r-k])%N)))%N);
					dynamic[i][r] = (int) (((long) dynamic[i][r] + ((long) (2*k*(r+1-k))*(((long) dynamic[i-1][k] * (long) dynamic[i-1][r+1-k])%N)))%N);
					dynamic[i][r] = (int) (((long) dynamic[i][r] + ((long) (2*k*(k+1))*(((long) dynamic[i-1][k+1] * (long) dynamic[i-1][r-k])%N)))%N);
				}
			}
		}

		System.out.println(dynamic[n][1]);

	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        static final long MODULO = (long) (1e9 + 7);

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int k = in.nextInt();
            long[][] comb = new long[k + 2][k + 2];
            comb[0][0] = 1;
            for (int a = 1; a < comb.length; ++a) {
                comb[a][0] = 1;
                for (int b = 1; b < comb.length; ++b) {
                    comb[a][b] = (comb[a - 1][b] + comb[a - 1][b - 1]) % MODULO;
                }
            }
            long[] p2 = new long[k + 2];
            p2[0] = 1;
            for (int i = 1; i < p2.length; ++i) p2[i] = 2 * p2[i - 1] % MODULO;
            long[][] res = new long[k + 1][k + 2];
            long[] ways = new long[k + 2];

            res[0][0] = 1;
            for (int size = 1; size <= k; ++size) {
                ways[0] = 1;
                for (int numpaths = 1; numpaths <= k + 1; ++numpaths) {
                    ways[numpaths] = 0;
                    for (int left = 0; left <= numpaths; ++left) {
                        ways[numpaths] = (ways[numpaths] + res[size - 1][left] * res[size - 1][numpaths - left] % MODULO * comb[numpaths][left]) % MODULO;
                    }
                }
                res[size][0] = 1;
                for (int numpaths = 1; numpaths <= k + 1; ++numpaths) {
                    long sum = ways[numpaths];
                    for (int joinleft = 0; joinleft <= 1; ++joinleft) {
                        for (int joinright = 0; joinright <= 1; ++joinright) {
                            int prevnumpaths = numpaths - 1 + joinleft + joinright;
                            if (prevnumpaths >= 0 && prevnumpaths <= k + 1) {
                                long cur = ways[prevnumpaths];
                            /*if (joinleft > 0) {
                                cur = cur * prevnumpaths % MODULO;
                                --prevnumpaths;
                            }
                            if (joinright > 0) {
                                cur = cur * prevnumpaths % MODULO;
                                --prevnumpaths;
                            }
                            if (joinleft > 0 && joinright > 0) {
                                cur = cur * inv2 % MODULO;
                            }*/
                                sum = (sum + cur * numpaths) % MODULO;
                            }
                        }
                    }
                    res[size][numpaths] = sum % MODULO;
                }
            }
            out.println(res[k][1]);
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}


import java.io.*;

public class P0424D {

	static final int MOD = 1000000007;

	long[][] binoms;

	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		int K = Integer.parseInt(br.readLine());

		long[][] dp = new long[K + 1][];

		for (int k = 0; k <= K; k++) {

			dp[k] = new long[K - k + 2];

			for (int p = 0; p < K - k + 2; p++) {

				if (p == 0) {
					dp[k][p] = 1;
				} else if (k == 0) {
					dp[k][p] = 0;
				} else {

					for (int i = 0; i <= p; i++) {
						dp[k][p] += dp[k - 1][i] * dp[k - 1][p - i];
						dp[k][p] %= MOD;
					}

					for (int i = 0; i <= p - 1; i++) {

						long inc = (dp[k - 1][i + 1] * dp[k - 1][p - i]) % MOD;
						inc *= 2 * (i + 1) * (p - i);
						dp[k][p] += inc % MOD;

						inc = (dp[k - 1][i + 2] * dp[k - 1][p - i - 1]) % MOD;
						inc *= 2 * (i + 2) * (i + 1);
						dp[k][p] += inc % MOD;

						inc = (dp[k - 1][i + 1] * dp[k - 1][p - i - 1]) % MOD;
						inc *= 4 * (i + 1);
						dp[k][p] += inc % MOD;

						dp[k][p] += dp[k - 1][i] * dp[k - 1][p - i - 1];
						dp[k][p] %= MOD;

					}
				}

			}

		}

		System.out.println(dp[K][1]);

	}

}


import java.io.*;
public class Coloring
{
    public static void main(String...args)throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        String[] st = s.trim().split("\\s+");
        int n = Integer.parseInt(st[0]);
        int m = Integer.parseInt(st[1]);

        if(n < m)
            n= swap(m , m = n);

        long mod = 998244353;

        long res[][] = new long[n+m][n];

        for(int i = 0 ; i < n+m ; i++){
            for(int j = 0 ; j < n ; j++){
                if(j == 0)
                    res[i][j] = 1;
                else if(i == 0)
                    res[i][j] = 0;
                else
                    res[i][j] = (res[i-1][j-1] + res[i-1][j]) % mod;
            }
        }

        long ans2 = 0;

        for(int rows = 1 ; rows < n ; rows++){
            long ans1 = 0;
            for(int col = m-1 ; col >= 1 ; col--){
                ans1 = (ans1 + res[n - rows + m - col -1][n - rows]*(res[n - rows + col - 1][n - rows - 1])) % mod;
                ans2 = (ans2 + res[rows + col -1][rows] * ((res[rows + m - col - 1][rows - 1] * ans1) % mod)) % mod;
            }
        }

        n= swap(m , m = n);
        //System.out.println(n+" "+m);
        for(int rows = 1 ; rows < n ; rows++){
            long ans1 = 0;
            for(int col = m-1 ; col >= 1 ; col--){
                ans2 = (ans2 + res[rows + col -1][rows] * ((res[rows + m - col - 1][rows - 1] * ans1) % mod)) % mod;
                ans1 = (ans1 + res[n - rows + m - col -1][n - rows]*(res[n - rows + col - 1][n - rows - 1])) % mod;
            }
        }

        ans2 = (ans2 * 2) % mod;
        System.out.println(ans2);

    }

    public static int swap(int...args){
        return args[0];
    }
}


//package round712;
import java.io.*;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Queue;

public class E3 {
	InputStream is;
	FastWriter out;
	String INPUT = "";
	final int mod = 998244353;
	long[][] C;

	void solve()
	{
		C = new long[4052 + 1][4052 + 1];
		for (int i = 0; i <= 4052; i++) {
			C[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
				if (C[i][j] >= mod) C[i][j] -= mod;
			}
		}

		int H = ni(), W = ni();

		long T = 0;
		// O(wh^4)
		for(int w = 1;w < W;w++) {
			long R = 0;
			for (int hl = 1; hl <= H; hl++) {
				// 0 <= hr <= H-1-hl
				// d(hl, w-1) * d(hr, w-1)
				// C[dr+w-1][w-1] * d(hl, w-1)
				int hll = H+1 - hl;
				R += d(hll, W-w-1) * C[H-1-hll+W-w][W-w];
				R %= mod;
				T += d(hl, w-1) * C[H-1-hl+w][w] % mod * R;
				T %= mod;
//				for (int hll = 0; hll <= H; hll++) {
//					if (hl + hll > H) {
//						T += d(hl, w-1) * C[H-1-hl+w][w] * d(hll, W-w-1) * C[H-1-hll+W-w][W-w];
//						T %= mod;
//					}
//				}
			}
		}
		T = T * 2;

		long IT = 0;
		// O(hw^4)
		for(int h = 1;h <= H-1;h++){
			// C[h-1+l][l]
			// C[h-1+r][r-1]
			long R = 0;
			for(int r = W-1;r >= 1;r--){
				R += d(H-h-1, r) * C[H-h+W-(r+1)][W-(r+1)];
				R %= mod;
				IT += C[h-1+r][r-1] * d(h-1, W-r) % mod * R;
				IT %= mod;
			}
		}
		IT *= 2;
		out.println((T+IT)%mod);
	}

	long d(int h, int w)
	{
		// begin:h, dec
		return C[h+w][h];
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new FastWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E3().run(); }

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private long[] nal(int n)
	{
		long[] a = new long[n];
		for(int i = 0;i < n;i++)a[i] = nl();
		return a;
	}

	private char[][] nm(int n, int m) {
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[][] nmi(int n, int m) {
		int[][] map = new int[n][];
		for(int i = 0;i < n;i++)map[i] = na(m);
		return map;
	}

	private int ni() { return (int)nl(); }

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	public static class FastWriter
	{
		private static final int BUF_SIZE = 1<<13;
		private final byte[] buf = new byte[BUF_SIZE];
		private final OutputStream out;
		private int ptr = 0;

		private FastWriter(){out = null;}

		public FastWriter(OutputStream os)
		{
			this.out = os;
		}

		public FastWriter(String path)
		{
			try {
				this.out = new FileOutputStream(path);
			} catch (FileNotFoundException e) {
				throw new RuntimeException("FastWriter");
			}
		}

		public FastWriter write(byte b)
		{
			buf[ptr++] = b;
			if(ptr == BUF_SIZE)innerflush();
			return this;
		}

		public FastWriter write(char c)
		{
			return write((byte)c);
		}

		public FastWriter write(char[] s)
		{
			for(char c : s){
				buf[ptr++] = (byte)c;
				if(ptr == BUF_SIZE)innerflush();
			}
			return this;
		}

		public FastWriter write(String s)
		{
			s.chars().forEach(c -> {
				buf[ptr++] = (byte)c;
				if(ptr == BUF_SIZE)innerflush();
			});
			return this;
		}

		private static int countDigits(int l) {
			if (l >= 1000000000) return 10;
			if (l >= 100000000) return 9;
			if (l >= 10000000) return 8;
			if (l >= 1000000) return 7;
			if (l >= 100000) return 6;
			if (l >= 10000) return 5;
			if (l >= 1000) return 4;
			if (l >= 100) return 3;
			if (l >= 10) return 2;
			return 1;
		}

		public FastWriter write(int x)
		{
			if(x == Integer.MIN_VALUE){
				return write((long)x);
			}
			if(ptr + 12 >= BUF_SIZE)innerflush();
			if(x < 0){
				write((byte)'-');
				x = -x;
			}
			int d = countDigits(x);
			for(int i = ptr + d - 1;i >= ptr;i--){
				buf[i] = (byte)('0'+x%10);
				x /= 10;
			}
			ptr += d;
			return this;
		}

		private static int countDigits(long l) {
			if (l >= 1000000000000000000L) return 19;
			if (l >= 100000000000000000L) return 18;
			if (l >= 10000000000000000L) return 17;
			if (l >= 1000000000000000L) return 16;
			if (l >= 100000000000000L) return 15;
			if (l >= 10000000000000L) return 14;
			if (l >= 1000000000000L) return 13;
			if (l >= 100000000000L) return 12;
			if (l >= 10000000000L) return 11;
			if (l >= 1000000000L) return 10;
			if (l >= 100000000L) return 9;
			if (l >= 10000000L) return 8;
			if (l >= 1000000L) return 7;
			if (l >= 100000L) return 6;
			if (l >= 10000L) return 5;
			if (l >= 1000L) return 4;
			if (l >= 100L) return 3;
			if (l >= 10L) return 2;
			return 1;
		}

		public FastWriter write(long x)
		{
			if(x == Long.MIN_VALUE){
				return write("" + x);
			}
			if(ptr + 21 >= BUF_SIZE)innerflush();
			if(x < 0){
				write((byte)'-');
				x = -x;
			}
			int d = countDigits(x);
			for(int i = ptr + d - 1;i >= ptr;i--){
				buf[i] = (byte)('0'+x%10);
				x /= 10;
			}
			ptr += d;
			return this;
		}

		public FastWriter write(double x, int precision)
		{
			if(x < 0){
				write('-');
				x = -x;
			}
			x += Math.pow(10, -precision)/2;
			//		if(x < 0){ x = 0; }
			write((long)x).write(".");
			x -= (long)x;
			for(int i = 0;i < precision;i++){
				x *= 10;
				write((char)('0'+(int)x));
				x -= (int)x;
			}
			return this;
		}

		public FastWriter writeln(char c){
			return write(c).writeln();
		}

		public FastWriter writeln(int x){
			return write(x).writeln();
		}

		public FastWriter writeln(long x){
			return write(x).writeln();
		}

		public FastWriter writeln(double x, int precision){
			return write(x, precision).writeln();
		}

		public FastWriter write(int... xs)
		{
			boolean first = true;
			for(int x : xs) {
				if (!first) write(' ');
				first = false;
				write(x);
			}
			return this;
		}

		public FastWriter write(long... xs)
		{
			boolean first = true;
			for(long x : xs) {
				if (!first) write(' ');
				first = false;
				write(x);
			}
			return this;
		}

		public FastWriter writeln()
		{
			return write((byte)'\n');
		}

		public FastWriter writeln(int... xs)
		{
			return write(xs).writeln();
		}

		public FastWriter writeln(long... xs)
		{
			return write(xs).writeln();
		}

		public FastWriter writeln(char[] line)
		{
			return write(line).writeln();
		}

		public FastWriter writeln(char[]... map)
		{
			for(char[] line : map)write(line).writeln();
			return this;
		}

		public FastWriter writeln(String s)
		{
			return write(s).writeln();
		}

		private void innerflush()
		{
			try {
				out.write(buf, 0, ptr);
				ptr = 0;
			} catch (IOException e) {
				throw new RuntimeException("innerflush");
			}
		}

		public void flush()
		{
			innerflush();
			try {
				out.flush();
			} catch (IOException e) {
				throw new RuntimeException("flush");
			}
		}

		public FastWriter print(byte b) { return write(b); }
		public FastWriter print(char c) { return write(c); }
		public FastWriter print(char[] s) { return write(s); }
		public FastWriter print(String s) { return write(s); }
		public FastWriter print(int x) { return write(x); }
		public FastWriter print(long x) { return write(x); }
		public FastWriter print(double x, int precision) { return write(x, precision); }
		public FastWriter println(char c){ return writeln(c); }
		public FastWriter println(int x){ return writeln(x); }
		public FastWriter println(long x){ return writeln(x); }
		public FastWriter println(double x, int precision){ return writeln(x, precision); }
		public FastWriter print(int... xs) { return write(xs); }
		public FastWriter print(long... xs) { return write(xs); }
		public FastWriter println(int... xs) { return writeln(xs); }
		public FastWriter println(long... xs) { return writeln(xs); }
		public FastWriter println(char[] line) { return writeln(line); }
		public FastWriter println(char[]... map) { return writeln(map); }
		public FastWriter println(String s) { return writeln(s); }
		public FastWriter println() { return writeln(); }
	}

	public void trnz(int... o)
	{
		for(int i = 0;i < o.length;i++)if(o[i] != 0)System.out.print(i+":"+o[i]+" ");
		System.out.println();
	}

	// print ids which are 1
	public void trt(long... o)
	{
		Queue<Integer> stands = new ArrayDeque<>();
		for(int i = 0;i < o.length;i++){
			for(long x = o[i];x != 0;x &= x-1)stands.add(i<<6|Long.numberOfTrailingZeros(x));
		}
		System.out.println(stands);
	}

	public void tf(boolean... r)
	{
		for(boolean x : r)System.out.print(x?'#':'.');
		System.out.println();
	}

	public void tf(boolean[]... b)
	{
		for(boolean[] r : b) {
			for(boolean x : r)System.out.print(x?'#':'.');
			System.out.println();
		}
		System.out.println();
	}

	public void tf(long[]... b)
	{
		if(INPUT.length() != 0) {
			for (long[] r : b) {
				for (long x : r) {
					for (int i = 0; i < 64; i++) {
						System.out.print(x << ~i < 0 ? '#' : '.');
					}
				}
				System.out.println();
			}
			System.out.println();
		}
	}

	public void tf(long... b)
	{
		if(INPUT.length() != 0) {
			for (long x : b) {
				for (int i = 0; i < 64; i++) {
					System.out.print(x << ~i < 0 ? '#' : '.');
				}
			}
			System.out.println();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
/**
 * Actual solution is at the top
 * @author  Tapan Sahni
 */

public class Tapan {
    public final  static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        //  Scanner in = new Scanner(inputStream);
        Reader in = new Reader();
        PrintWriter out = new PrintWriter(outputStream);
        Task_C solver = new Task_C();
        solver.solve( in, out);
        out.close();
    }
}
class Task_C {

    @SuppressWarnings("unused")

    public long step (long  a , long  b , long k){
        long ret = 0;
             while(a > b){
                 long Max = 1;
                 for(long i = 2 ;i<= k;i++ ){
                    long l1 = a%i;
                    if(a - l1 >= b)
                  Max = Math.max(Max, l1);
                 }
                 if(Max  == 0) Max = 1;
                 a-=Max;
                 ret++;
                }
             return ret;
    }
    public void solve(Reader in, PrintWriter out) throws IOException {
             long a = in.nextLong() , b = in.nextLong();
             long k = in.nextLong();
            long L = 360360L;
            if(a - b <= L) out.println(step(a , b , k));
            else{
             long ans = step(a%L , 0 , k);
             ans = ans + (long)step(L , 0 , k) * (a/L - b/L -1);
             ans = ans + (long)step(L ,b%L , k);
             out.println(ans);
          }
    }
}
class Reader {
    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader() {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException {
        byte[] buf = new byte[1001]; // line length
        int cnt = 0, c;
        while ((c = read()) != -1) {
            if (c == '\n')
                break;
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException {
        int ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public long nextLong() throws IOException {
        long ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public double nextDouble() throws IOException {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        if (c == '.')
            while ((c = read()) >= '0' && c <= '9')
                ret += (c - '0') / (div *= 10);
        if (neg)
            return -ret;
        return ret;
    }

    public char nextChar() throws IOException {
        byte c = read();
        while (c <= ' ')
            c = read();
        return (char) c;
    }

    private void fillBuffer() throws IOException {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1)
            buffer[0] = -1;
    }

    private byte read() throws IOException {
        if (bufferPointer == bytesRead)
            fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException {
        if (din == null)
            return;
        din.close();
    }
}
class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class E {

    static int find(fenwik_tree t, int y, int lo, int hi) {
        while(lo<=hi) {
            int mid=(lo+hi)>>1;
            long cnt=t.query(0, mid);

            if(cnt<y) {
                lo=mid+1;
            } else {
                hi=mid-1;
            }
        }
        return hi+1;
    }

    static void run_stream(InputStream ins) throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String[] nm=br.readLine().split(" ");
        int n=Integer.parseInt(nm[0]);
        int m=Integer.parseInt(nm[1]);

        int[] i2c=new int[n+m+1];
        fenwik_tree t=new fenwik_tree(n+m+1);
        for (int i=1; i<=n; i++) {
            t.update(m+i, 1);
            i2c[m+i]=i;
        }

        int[] out=new int[n+1];
        for (int i=0; i<m; i++) {
            String[] xy=br.readLine().split(" ");
            int x=Integer.parseInt(xy[0]);
            int y=Integer.parseInt(xy[1]);

            int j=find(t, y, m-i, n+m), k=i2c[j];
            if(out[k]>0&&out[k]!=x) {
                System.out.println("-1");
                return;
            } else {
                out[k]=x;
            }
            t.update(j,-1);  i2c[j]=-1;
            t.update(m-i,1); i2c[m-i]=k;
        }

        boolean[] b=new boolean[n+1]; int j=1;
        for (int i=1; i<=n; i++) {
            if(out[i]!=0) {
                if(b[out[i]]) {
                    System.out.println("-1");
                    return;
                }
                b[out[i]]=true;
            }
        }

        for (int i=1; i<=n; i++) {
            if(out[i]==0) {
                while(b[j]) {
                    j++;
                }
                out[i]=j;
            }
            b[out[i]]=true;
        }

        StringBuilder sb=new StringBuilder();
        for (int i=1; i<=n; i++) {
            sb.append(out[i]+" ");
        }
        System.out.println(sb.toString());
    }

    public static void main(String[] args) throws IOException {
        run_stream(System.in);
    }

    static class fenwik_tree {
        int n;
        long[] fadd;

        fenwik_tree(int n) {
            this.n=n; fadd=new long[n];
        }

        void update(int i, long add) {
            while (i<n) {
                fadd[i]+=add;
                i|=(i+1);
            }
        }

        long query(int i) {
            long ret=0;
            while (i>=0) {
                ret+=fadd[i];
                i=(i&(i+1))-1;
            }
            return ret;
        }

        long query(int l, int r) {
            return query(r)-query(l-1);
        }
    }

}


import java.util.*;
import java.io.*;

public class PuttingBoxesTogether {
    static final long MOD = 1000000007L;
    public static void main(String[] args) {
        FastScanner scanner = new FastScanner();
        PrintWriter out = new PrintWriter(System.out);
        int N = scanner.nextInt();
        int Q = scanner.nextInt();
        long[] pos = new long[N];
        long[] weights = new long[N];
        BIT bit1 = new BIT(N);
        BIT bit2 = new BIT(N);
        for(int i = 0; i < N; i++) {
            pos[i] = scanner.nextInt();
        }
        for(int i  = 0; i < N; i++) weights[i] = scanner.nextInt();
        for(int i = 0; i < N; i++) {
            pos[i] -= i;
            bit1.update(i, weights[i]);
            bit2.update(i, (weights[i] * pos[i])%MOD);
        }
        while(Q-->0) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            if (x < 0) {
                //update event
                x = -x -1;
                bit1.update(x, -weights[x]);
                bit2.update(x, -((weights[x]*pos[x])%MOD));
                weights[x] = y;
                bit1.update(x, weights[x]);
                bit2.update(x, (weights[x]*pos[x])%MOD);
            }
            else {
                x--;
                long s = bit1.rangeSum(x, y);
                int lo = x, hi = y;
                while (hi - lo > 1) {
                    int mid = (lo + hi)/2;
                    if (bit1.rangeSum(x, mid) * 2 <= s) lo = mid;
                    else hi = mid;
                }
                long ret = norm(mul(pos[lo], norm(bit1.rangeSum(x, lo))) - norm(bit2.rangeSum(x, lo)));
                ret = norm(ret + norm(norm(bit2.rangeSum( lo + 1, y)) - mul(pos[lo], norm(bit1.rangeSum(lo + 1, y)))));
                out.println(ret );

            }
        }
        out.flush();
    }
    static long mul(long a, long b) {
        return a * b % MOD;
    }

    static long norm(long a) {
        a %= MOD;
        if (a > MOD) a -= MOD;
        if (a < 0) a += MOD;
        return a;
    }
    public static class BIT {
        long[] table;
        int size;
        public BIT(int ss) {
            size = ss;
            table = new long[ss];
        }
        private void update(int loc, long amt) {
            for (int x = loc; x < size; x = x | x + 1) table[x] += amt;
        }
        private long prefixSum(int loc) {
            long res = 0;
            for (int x = loc; x >= 0; x = (x & x + 1) - 1) res += table[x];
            return res;
        }
        private long rangeSum(int l, int r) {
            return prefixSum(r-1) - prefixSum(l-1);
        }
    }
    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(Reader in) {
            br = new BufferedReader(in);
        }

        public FastScanner() {
            this(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String readNextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        int[] readIntArray(int n) {
            int[] a = new int[n];
            for (int idx = 0; idx < n; idx++) {
                a[idx] = nextInt();
            }
            return a;
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

/**
 * @author Don Li
 */
public class PuttingBoxesTogether2 {

    int N = (int) 2e5 + 10;
    int MOD = (int) 1e9 + 7;
    int INF = (int) 2e9;

    int n;
    long[] t1 = new long[N << 2];
    long[] t2 = new long[N << 2];

    void solve() {
        n = in.nextInt(); int Q = in.nextInt();
        long[] a = new long[n];
        for (int i = 0; i < n; i++) a[i] = in.nextInt();
        long[] w = new long[n];
        for (int i = 0; i < n; i++) w[i] = in.nextInt();

        for (int i = 0; i < n; i++) a[i] -= i;

        long[] aw = new long[n];
        for (int i = 0; i < n; i++) aw[i] = mul(a[i], w[i]);

        build(t1, 0, 0, n, w);
        build(t2, 0, 0, n, aw);

        while (Q-- > 0) {
            int x = in.nextInt();
            if (x < 0) {
                int i = -x - 1, nw = in.nextInt();
                update(t1, 0, 0, n, i, nw);
                update(t2, 0, 0, n, i, mul(a[i], nw));
            } else {
                int l = x - 1, r = in.nextInt();
                long tot = query(t1, 0, 0, n, l, r);
                int k = (int) find(t1, 0, 0, n, l, r, tot / 2)[0];
                long ans = norm(mul(a[k], norm(query(t1, 0, 0, n, l, k))) - norm(query(t2, 0, 0, n, l, k)));
                ans = norm(ans + norm(norm(query(t2, 0, 0, n, k + 1, r)) - mul(a[k], norm(query(t1, 0, 0, n, k + 1, r)))));
                out.println(ans);
            }
        }
    }

    long[] find(long[] t, int k, int l, int r, int a, int b, long val) {
        if (l == a && r == b) {
            if (t[k] <= val) return new long[]{INF, t[k]};
            if (r - l == 1) return new long[]{l, t[l]};
        }
        int m = (l + r) >> 1;
        long pos = INF, sum = 0;
        if (a < m) {
            long[] ret = find(t, 2 * k + 1, l, m, a, Math.min(m, b), val);
            pos = Math.min(pos, ret[0]);
            sum += ret[1];
        }
        if (pos == INF && b >= m) {
            long[] ret = find(t, 2 * k + 2, m, r, Math.max(m, a), b, val - sum);
            pos = Math.min(pos, ret[0]);
            sum += ret[1];
        }
        return new long[]{pos, sum};
    }

    long query(long[] t, int k, int l, int r, int a, int b) {
        if (a <= l && r <= b) return t[k];
        if (a >= r || b <= l) return 0;
        int m = (l + r) >> 1;
        return query(t, 2 * k + 1, l, m, a, b) + query(t, 2 * k + 2, m, r, a, b);
    }

    void update(long[] t, int k, int l, int r, int i, long val) {
        if (r - l == 1) {
            t[k] = val;
            return;
        }
        int m = (l + r) >> 1;
        if (i < m) update(t, 2 * k + 1, l, m, i, val);
        else update(t, 2 * k + 2, m, r, i, val);
        t[k] = t[2 * k + 1] + t[2 * k + 2];
    }

    void build(long[] t, int k, int l, int r, long[] x) {
        if (r - l == 1) {
            t[k] = x[l];
            return;
        }
        int m = (l + r) >> 1;
        build(t, 2 * k + 1, l, m, x);
        build(t, 2 * k + 2, m, r, x);
        t[k] = t[2 * k + 1] + t[2 * k + 2];
    }

    long mul(long a, long b) {
        return a * b % MOD;
    }

    long norm(long a) {
        a %= MOD;
        if (a > MOD) a -= MOD;
        if (a < 0) a += MOD;
        return a;
    }

    public static void main(String[] args) {
        in = new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(System.out);
        new PuttingBoxesTogether2().solve();
        out.close();
    }

    static FastScanner in;
    static PrintWriter out;

    static class FastScanner {
        BufferedReader in;
        StringTokenizer st;

        public FastScanner(BufferedReader in) {
            this.in = in;
        }

        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(in.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        public long nextLong() {
            return Long.parseLong(nextToken());
        }

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }
}