// package Quarantine;

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

public class HeightAllTheSame {
    public static void main(String[] args)throws IOException {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer(br.readLine());
        int n=Integer.parseInt(st.nextToken());
        int m=Integer.parseInt(st.nextToken());
        int l=Integer.parseInt(st.nextToken());
        int r=Integer.parseInt(st.nextToken());
        long total=1l*n*m;
        int mod=998244353;
        if(total%2!=0){
            long ans=modexp(r-l+1,total,mod);
            System.out.println(ans);
        }
        else{
            int k=r-l+1;
            int e=r/2-l/2;
            if(l%2==0){
                e++;
            }
            int o=k-e;
//            System.out.println(e+" "+o);
            long ans=modexp(e+o,total,mod);
            ans=(ans+modexp(e-o,total,mod))%mod;
            ans=(ans*modexp(2,mod-2,mod))%mod;
            System.out.println(ans);
        }
    }
    public static long modexp(long a,long power,int mod){
        if(power==0){
            return 1;
        }
        if(power==1){
            return a;
        }
        long small=modexp(a,power/2,mod);
        long ans=(small%mod*small%mod)%mod;
        if(power%2!=0){
            ans=(ans%mod*a%mod)%mod;
        }
        return ans;
    }
}


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

public class E {

	static long mod = 998244353;
	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		long n = sc.nextInt();
		long m = sc.nextInt();
		long L = sc.nextInt();
		long R = sc.nextInt();
		if(n % 2 == 1 && m % 2 == 1) {
			System.out.println(pow((R-L+1) % mod, n*m));
		}
		else {
			if((R - L + 1) % 2 == 0) {
				long allbutone = pow((R-L+1) % mod, n*m-1);
				long res = allbutone * ((R-L+1)/2) % mod;
				System.out.println(res);
			}
			else { //fun case
				Matrix id = new Matrix(1,0,0,1);
				long k = (R - L + 1) / 2;
				Matrix mat = new Matrix(k, k+1, k+1, k);
				Matrix res = mat.pow(n*m);
				System.out.println(res.mat[0][0]);
			}
		}
	}
	static class Matrix{
		long[][] mat = new long[2][2];
		public Matrix(long a, long b, long c, long d) {
			mat[0][0] = a;
			mat[0][1] = b;
			mat[1][0] = c;
			mat[1][1] = d;
		}
		public Matrix(long[][] mat) {
			this.mat = mat;
		}
		public Matrix pow(long x) {
			Matrix res = new Matrix(1, 0, 0, 1);
			Matrix a = new Matrix(mat);
			while(x > 0) {
				if(x % 2 == 1) {
					res = res.mult(a);
				}
				a = a.mult(a);
				x /= 2;
			}
			return res;
		}
		public Matrix mult(Matrix m) {
			long[][] rmat = new long[2][2];
			for(int i = 0; i < 2; i++) {
				for(int j = 0; j < 2; j++) {
					for(int k = 0; k < 2; k++) {
						rmat[i][j] += mat[i][k] * m.mat[k][j];
						rmat[i][j] %= mod;
					}
				}
			}
			return new Matrix(rmat);
		}
		public String toString() {
			return
			mat[0][0]+" "+mat[0][1]+"\n"+
			mat[1][0]+" "+mat[1][1];
		}
	}

	static long pow(long a, long b) {
		long res = 1;
		while(b > 0) {
			if(b % 2 == 1) {
				res = (res * a) % mod;
			}
			a = (a * a) % mod;
			b /= 2;
		}
		return res;
	}

	static class FastScanner {
		public BufferedReader reader;
		public StringTokenizer tokenizer;
		public FastScanner() {
			reader = new BufferedReader(new InputStreamReader(System.in), 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());
		}
		public double nextDouble() {
			return Double.parseDouble(next());
		}
		public String nextLine() {
			try {
				return reader.readLine();
			} catch(IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

}


//package Div2_630;
//564 558 305171115 960941497

import java.util.Scanner;
import java.util.TreeMap;

public class E {
    static long mod = 998244353;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long n = in.nextInt();
        long m = in.nextInt();
        long p = in.nextInt();
        long q = in.nextInt();
        long x = q - p + 1;
        if (p % 2 == 0) x = x - x / 2;
        else x /= 2;
        long y = q - p + 1 - x;
        dp[0]=new TreeMap();
        dp[1]=new TreeMap();
        if ((n & m) % 2 == 0) {
            long ans = fn(x, y, n * m, 0);
            System.out.println(ans);
        } else {
            long ans = bin(x + y, n * m);
            System.out.println(ans);
        }
    }

    static TreeMap<Long, Integer>[] dp = new TreeMap[2];

    private static long fn(long x, long y, long st, int type) {
        if (dp[type].containsKey(st)) return dp[type].get(st);
        if (st == 1) {
            if (type == 0) return x;
            return y;
        }
        if (st % 2 == 1) {
            return (x * fn(x, y, st - 1, type) + y * fn(x, y, st - 1, (type + 1) % 2)) % mod;
        } else {
            long nch = fn(x, y, st / 2, 1);
            long ch = fn(x, y, st / 2, 0);
            long ans = 0;
            if (type == 0) {
                ans = (ch * ch + nch * nch) % mod;
            } else {
                ans = (2 * ch * nch) % mod;
            }
            dp[type].put(st, (int) ans);
            return ans;
        }
    }

    private static long bin(long x, long st) {
        if (st == 0) return 1;
        if (st == 1) return x;
        long m = st / 2;
        long ans = bin(x, m);
        if (st % 2 == 0) {
            return (ans * ans) % mod;
        } else {
            return (((ans * ans) % mod) * x) % mod;
        }
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

/*
Прокрастинирую
*/

public class Main {

    static FastReader in;
    static PrintWriter out;
    static Random rand = new Random();
    static final int INF = (int) (1e9 + 10), MOD = (int) (998244353), LOGN = 20;
    static final long IINF = (long) (2e18 + 10);

    static long pow(long a, long b) {
        long res = 1;
        while (b != 0) {
            if ((b & 1) != 0) {
                res = (res * a) % MOD;
            }
            a = (a * a) % MOD;
            b >>= 1;
        }
        return res;
    }

    static long even, odd;
    static HashMap<Long, Long> dp0;
    static HashMap<Long, Long> dp1;
    static long go(long n, int x) {
        if (x == 0) {
            if (dp0.containsKey(n)) {
                return dp0.get(n);
            }
            if (n == 1) {
                long res = even;
                dp0.put(n, res);
                return res;
            } else if (n == 2) {
                long res = (even * even + odd * odd) % MOD;
                dp0.put(n, res);
                return res;
            }
            long a1 = go(n / 2, 0);
            long a2 = go(n - n / 2, 0);
            long b1 = go(n / 2, 1);
            long b2 = go(n - n / 2, 1);
            long res = (a1 * a2 + b1 * b2) % MOD;
            dp0.put(n, res);
            return res;
        } else {
            if (dp1.containsKey(n)) {
                return dp1.get(n);
            }
            if (n == 1) {
                long res = odd;
                dp1.put(n, res);
                return res;
            } else if (n == 2) {
                long res = (even * odd + odd * even) % MOD;
                dp1.put(n, res);
                return res;
            }
            long a1 = go(n / 2, 0);
            long a2 = go(n - n / 2, 1);
            long b1 = go(n / 2, 1);
            long b2 = go(n - n / 2, 0);
            long res = (a1 * a2 + b1 * b2) % MOD;
            dp1.put(n, res);
            return res;
        }
    }

    static void solve() {
        long n = in.nextInt();
        long m = in.nextInt();
        long l = in.nextInt();
        long r = in.nextInt();
        long sz = n * m;

        if (sz % 2 == 0) {
            even = (r - l + 1) / 2;
            if ((r - l) % 2 == 0 && l % 2 == 0) even++;
            odd = r - l + 1 - even;

            dp0 = new HashMap<>();
            dp1 = new HashMap<>();
            out.println(go(sz, 0));
        } else {
            long ans = pow(r - l + 1, sz);
            out.println(ans);
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        in = new FastReader(System.in);
//        in = new FastReader(new FileInputStream("sometext.txt"));
        out = new PrintWriter(System.out);
//        out = new PrintWriter(new FileOutputStream("sometext.txt"));

        int tests = 1;
//        tests = in.nextInt();

        while (tests-- > 0) {
            solve();
        }

//        out.flush();
        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

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

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

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

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }

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


/*****Author: Satyajeet Singh, Delhi Technological University************************************/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;
public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static HashSet<Integer> graph[];
    static int pptr=0,pptrmax=0;
    static String st[];
/*****************************************Solutions Begins***************************************/
    public static void main(String args[]) throws Exception{
        long n=pl();
        long m=pl();
        long l=pl();
        long r=pl();
        long d=r-l+1;
        long a=d/2;
        long b=d-a;
        long nm=n*m;
        mod=mod1;
        //debug(a,b);

        long ans=(modulo((a+b),nm,mod)+modulo(Math.abs(a-b),nm,mod))%mod;
        ans=(ans*modulo(2l,mod-2,mod))%mod;
        if(nm%2==1){
            ans=modulo(d,nm,mod);
        }
        out.println(ans);
/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }
/****************************************Template Begins************************************************/
    static void nl() throws Exception{
        pptr=0;
        st=br.readLine().split(" ");
        pptrmax=st.length;
    }
    static void nls() throws Exception{
        pptr=0;
        st=br.readLine().split("");
        pptrmax=st.length;
    }
    static int pi() throws Exception{
        if(pptr==pptrmax)
            nl();
        return Integer.parseInt(st[pptr++]);
    }
    static long pl() throws Exception{
        if(pptr==pptrmax)
            nl();
        return Long.parseLong(st[pptr++]);
    }
    static double pd() throws Exception{
        if(pptr==pptrmax)
            nl();
        return Double.parseDouble(st[pptr++]);
    }
    static String ps() throws Exception{
        if(pptr==pptrmax)
            nl();
        return st[pptr++];
    }
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.000000000000");
        out.print(ft.format(d));
    }
/**************************************Bit Manipulation**************************************************/
    static void printMask(long mask){
        System.out.println(Long.toBinaryString(mask));
    }
    static int countBit(long mask){
        int ans=0;
        while(mask!=0){
            mask&=(mask-1);
            ans++;
        }
        return ans;
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new HashSet[n];
        for(int i=0;i<n;i++){
            graph[i]=new HashSet<>();
        }
    }
    static void addEdge(int a,int b){
        graph[a].add(b);
    }
    // static void addEdge(int a,int b,int c){
    //     graph[a].add(new Pair(b,c));
    // }
/*********************************************PAIR********************************************************/
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }
        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }
        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }
        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }
        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*******************************************************/
    static class Pairl implements Comparable<Pairl> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }
            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }
            public boolean equals(Object o) {
                Pairl other = (Pairl) o;
                return u == other.u && v == other.v;
            }
            public int compareTo(Pairl other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }
            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o){
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c){
        long x=1;
        long y=a%c;
        while(b > 0){
            if(b%2 == 1)
                x=(x*y)%c;
            y = (y*y)%c;
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y){
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y;
        b = (x < y) ? x : y;
        r = b;
        while(a % b != 0){
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/********************************************End***********************************************************/
}


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

public class Solution{

	static long mod = 998244353L;

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

		FastScanner fs = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);

		long n = fs.nextLong(), m = fs.nextLong(), l = fs.nextLong(), r = fs.nextLong();

		if((n*m&1)==1) {
			out.println(exp(r-l+1,n*m));
			out.close();
			return;
		}

		long E = r/2 - (l-1)/2;
		long O = r-l+1 - E;

		long ans = (exp(E+O,n*m) + exp(E-O,n*m))%mod;
		ans = (ans*exp(2,mod-2))%mod;

		out.println(ans);

		out.close();
	}

	//BINARY EXPONENTIATION
	static long exp(long a, long n) {
		long res = 1L;
		while(n>0) {
			if((n&1)==1) {
				res = (res*a)%mod;
			}
			a = (a*a)%mod;
			n = n>>1;
		}
		return res;
	}

	static class FastScanner{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");

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

		public String nextLine() throws IOException {
			return br.readLine();
		}

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

		public int[] readArray(int n){
			int[] a = new int[n];
			for(int i=0;i<n;i++)
				a[i] = nextInt();
			return a;
		}

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

}


import java.io.*;
import java.text.*;
import java.util.*;
import java.math.*;

public class E {
	public static void main(String[] args) throws Exception {
		new E().run();
	}
	public void run() throws Exception {
		FastScanner f = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		int n = f.nextInt();
		int m = f.nextInt();
		int l = f.nextInt();
		int r = f.nextInt();
		if(n % 2 == 1 && m % 2 == 1) {
			out.println(exp(exp(r-l+1, n), m));
			out.flush();
			return;
		}
		int even = r/2-(l+1)/2+1;
		int odd = r-l+1-even;
		long[][] mat = {{even, odd},{odd, even}};
		mat = exp(mat, n);
		mat = exp(mat, m);
		out.println(mat[0][0]);
///
		out.flush();
	}
	public int MOD = 998_244_353;
	public long[][] mult(long[][] a, long[][] b) {
		long[][] c = new long[a.length][b[0].length];
		for(int i = 0; i < a.length; i++)
			for(int j = 0; j < b[0].length; j++)
				for(int k = 0; k < b.length; k++)
					c[i][j] = (c[i][j] + a[i][k] * b[k][j] % MOD) % MOD;
		return c;
	}
	public long[][] exp(long[][] m, int e) {
		if(e == 1) return m;
		long[][] r = exp(m, e >> 1);
		r = mult(r, r);
		if(e%2 == 1)
			r = mult(r, m);
		return r;
	}
	public long exp(long a, int e) {
		if(e == 1) return a;
		long r = exp(a, e >> 1);
		r = r*r%MOD;
		if(e % 2 == 1)
			r = r*a % MOD;
		return r;
	}
///
    static class FastScanner {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
        public FastScanner() {
            reader = new BufferedReader(new InputStreamReader(System.in), 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());
        }
        public double nextDouble() {
        	return Double.parseDouble(next());
        }
        public String nextLine() {
        	try {
        		return reader.readLine();
        	} catch(IOException e) {
        		throw new RuntimeException(e);
        	}
        }
    }
}


/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class E
   {
      static long MOD = 998244353L;
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         long N = Long.parseLong(st.nextToken());
         long M = Long.parseLong(st.nextToken());
         long L = Long.parseLong(st.nextToken());
         long R = Long.parseLong(st.nextToken());
         //dont panic
         //that makes you lose Omkar energy
         if((N*M)%2 == 1)
         {
            //here?
            long temp = N*M;
            BigInteger exp = new BigInteger(temp+"");
            BigInteger base = new BigInteger((R-L+1)+"");
            BigInteger mod = new BigInteger(MOD+"");
            long res = base.modPow(exp, mod).longValue();
            System.out.println((res+MOD)%MOD);
         }
         else
         {
            long temp = N*M;
            BigInteger exp = new BigInteger(temp+"");
            BigInteger base = new BigInteger((R-L+1)+"");
            BigInteger mod = new BigInteger(MOD+"");
            long res = base.modPow(exp, mod).longValue();
            //res = (res*power(2,MOD-2,MOD))%MOD;
            if((R-L)%2 == 0)
               res++;
            res = (res*power(2,MOD-2,MOD))%MOD;
            System.out.println(res);
         }
      }
      public static long power(long x, long y, long p)
      {
          long res = 1L;
          x = x % p;
          while (y > 0)
          {
              if((y & 1)==1)
                  res = (res * x) % p;
              y = y >> 1;
              x = (x * x) % p;
          }
          return res;
      }
   }


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

public class E implements Runnable {
	boolean judge = false;
	FastReader scn;
	PrintWriter out;
	String INPUT = "";

	void solve() {
		long n = scn.nextLong(), m = scn.nextLong();
		long l = scn.nextLong(), r = scn.nextLong(), mod = 998244353;

		if((n * m) % 2 == 1) {
			out.println(pow(r - l + 1, n * m, mod));
			return;
		}

		long x = (r - l + 1) / 2;
		long k = n * m;
		long two = pow(2, k - 1, mod);

		long ans = (pow(x, k, mod) * two) % mod;
		if((r - l + 1) % 2 != 0) {
			long y = r - l + 1 - x;
			ans = (pow(y + x, k, mod) + pow(y - x, k, mod)) % mod;
			ans = (ans * pow(2, mod - 2, mod)) % mod;
		}
		out.println(ans);
	}

	long func(long k, long z, long mod) {
		if(z == 0) {
			return 0;
		}
		long x = z / 2, y = z - x;
		if(x == 0 || y == 0) {
			return 1;
		}

		long ans = 0;
		for(long a = 0; a <= k; a += 2) {
			long b = k - a;

			long rv = pow(x, a, mod) * pow(y, b, mod) % mod;
			ans = (ans + rv) % mod;
		}

		return ans;
	}

	long pow(long a, long x, long m) {
		long rv = 1;
		while (x != 0) {
			if ((x & 1) == 1) {
				rv = (rv * a) % m;
			}
			a = (a * a) % m;
			x = x >> 1;
		}
		return rv;
	}

	public void run() {
		long time = System.currentTimeMillis();
		boolean oj = System.getProperty("ONLINE_JUDGE") != null || judge;
		out = new PrintWriter(System.out);
		scn = new FastReader(oj);
		solve();
		out.flush();
		if (!oj) {
			System.out.println(Arrays.deepToString(new Object[] { System.currentTimeMillis() - time + " ms" }));
		}
	}

	public static void main(String[] args) {
		new Thread(null, new E(), "Main", 1 << 28).start();
	}

	class FastReader {
		InputStream is;

		public FastReader(boolean onlineJudge) {
			is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		}

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

		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++];
		}

		boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

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

		char nextChar() {
			return (char) skip();
		}

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

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

		char[] next(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);
		}

		int nextInt() {
			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();
			}
		}

		long nextLong() {
			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();
			}
		}

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

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

		long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++)
				a[i] = nextLong();
			return a;
		}

		int[][] next2DInt(int n, int m) {
			int[][] arr = new int[n][];
			for (int i = 0; i < n; i++) {
				arr[i] = nextIntArray(m);
			}
			return arr;
		}

		long[][] next2DLong(int n, int m) {
			long[][] arr = new long[n][];
			for (int i = 0; i < n; i++) {
				arr[i] = nextLongArray(m);
			}
			return arr;
		}

		int[] shuffle(int[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				int c = arr[i];
				arr[i] = arr[j];
				arr[j] = c;
			}
			return arr;
		}

		long[] shuffle(long[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				long c = arr[i];
				arr[i] = arr[j];
				arr[j] = c;
			}
			return arr;
		}

		int[] uniq(int[] arr) {
			arr = scn.shuffle(arr);
			Arrays.sort(arr);
			int[] rv = new int[arr.length];
			int pos = 0;
			rv[pos++] = arr[0];
			for (int i = 1; i < arr.length; i++) {
				if (arr[i] != arr[i - 1]) {
					rv[pos++] = arr[i];
				}
			}
			return Arrays.copyOf(rv, pos);
		}

		long[] uniq(long[] arr) {
			arr = scn.shuffle(arr);
			Arrays.sort(arr);
			long[] rv = new long[arr.length];
			int pos = 0;
			rv[pos++] = arr[0];
			for (int i = 1; i < arr.length; i++) {
				if (arr[i] != arr[i - 1]) {
					rv[pos++] = arr[i];
				}
			}
			return Arrays.copyOf(rv, pos);
		}

		int[] reverse(int[] arr) {
			int l = 0, r = arr.length - 1;
			while (l < r) {
				arr[l] = arr[l] ^ arr[r];
				arr[r] = arr[l] ^ arr[r];
				arr[l] = arr[l] ^ arr[r];
				l++;
				r--;
			}
			return arr;
		}

		long[] reverse(long[] arr) {
			int l = 0, r = arr.length - 1;
			while (l < r) {
				arr[l] = arr[l] ^ arr[r];
				arr[r] = arr[l] ^ arr[r];
				arr[l] = arr[l] ^ arr[r];
				l++;
				r--;
			}
			return arr;
		}

		int[] compress(int[] arr) {
			int n = arr.length;
			int[] rv = Arrays.copyOf(arr, n);
			rv = uniq(rv);
			for (int i = 0; i < n; i++) {
				arr[i] = Arrays.binarySearch(rv, arr[i]);
			}
			return arr;
		}

		long[] compress(long[] arr) {
			int n = arr.length;
			long[] rv = Arrays.copyOf(arr, n);
			rv = uniq(rv);
			for (int i = 0; i < n; i++) {
				arr[i] = Arrays.binarySearch(rv, arr[i]);
			}
			return arr;
		}
	}
}


import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.io.PrintWriter;
import java.io.InputStream;

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

class TaskD {
    static long [][] mod;
    static long modulo = 1000000007;

    static long exp(long a, long pow) {
        long ans = 1;
        while(pow > 0) {
           if(pow%2 == 1) ans = ans*a%modulo;
           pow >>= 1;
           a = a*a%modulo;
        }
        return ans;
    }

    static void compute( int n, long q )
    {
        mod = new long[2][ n+1 ];
        mod[0][0] = 1;
        for (int i = 1; i <= n; i++) {
            mod[0][i] = mod[0][i-1]*(n-i+1)%modulo*exp(i, modulo-2)%modulo;
        }

        for(int i = 0; i <= n; ++i) {
            long temp = mod[0][i];
            mod[0][i] = exp(mod[0][i], q);
            mod[1][i] = mod[0][i]*temp%modulo;
        }

    }

	public void solve(int testNumber, Scanner in, PrintWriter out) {

        int n = in.nextInt();
        long m = in.nextLong();
        int k = in.nextInt();
        compute(n,m/n);
        long [][] f = new long[n+1][k+1];

        Arrays.fill(f[0], 0);
        f[0][0] = 1;

        for(int i = 1; i <= n; ++i) {
            f[i][0] = 1;
            int d = 0;
            if(i<=m%n) d++;

            for(int j = 1; j <= k; ++j) {
                f[i][j] = 0;
                for(int l = 0; l <= j && l <= n; ++l)
                    f[i][j] = (f[i][j] + mod[d][l]*f[i-1][j-l])%modulo;
            }
        }
/*
        for(int i = 0; i <= n; ++i) {
            for(int j = 0; j <= k; ++j)
                out.write(f[i][j] + " ");
            out.println("");
        } */
        out.println(new Long(f[n][k]).toString());
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

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

    static class C1HaidiITestTyuringaLegkaya {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int n = in.readInt();
            int minX = Integer.MAX_VALUE;
            int minY = Integer.MAX_VALUE;
            int maxX = Integer.MIN_VALUE;
            int maxY = Integer.MIN_VALUE;
            int[] cntX = new int[51];
            int[] cntY = new int[51];
            IntIntPair[] a = in.readIntPairArray(4 * n + 1);
            for (IntIntPair p : a) {
                cntX[p.first]++;
                cntY[p.second]++;
//            minX = Math.min(minX, p.first);
//            minY = Math.min(minY, p.second);
//            maxX = Math.max(maxX, p.first);
//            maxY = Math.max(maxY, p.second);
            }
            for (int x = 0; x <= 50; x++) {
                if (cntX[x] >= n) {
                    minX = Math.min(minX, x);
                    maxX = Math.max(maxX, x);
                }
            }
            for (int y = 0; y <= 50; y++) {
                if (cntY[y] >= n) {
                    minY = Math.min(minY, y);
                    maxY = Math.max(maxY, y);
                }
            }
            for (IntIntPair p : a) {
                boolean fail = false;
                if ((p.first == minX || p.first == maxX)) {
                    fail = p.second < minY || p.second > maxY;
                } else if ((p.second == minY || p.second == maxY)) {
                    fail = p.first < minX || p.first > maxX;
                } else {
                    fail = true;
                }
                if (fail) {
                    out.print(p.first, p.second);
                }
            }
        }

    }

    static class IntIntPair implements Comparable<IntIntPair> {
        public final int first;
        public final int second;

        public IntIntPair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            IntIntPair pair = (IntIntPair) o;

            return first == pair.first && second == pair.second;
        }

        public int hashCode() {
            int result = first;
            result = 31 * result + second;
            return result;
        }

        public String toString() {
            return "(" + first + "," + second + ")";
        }

        public int compareTo(IntIntPair o) {
            int value = Integer.compare(first, o.first);
            if (value != 0) {
                return value;
            }
            return Integer.compare(second, o.second);
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void close() {
            writer.close();
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public IntIntPair[] readIntPairArray(int size) {
            IntIntPair[] result = new IntIntPair[size];
            for (int i = 0; i < size; i++) {
                result[i] = readIntPair();
            }
            return result;
        }

        public IntIntPair readIntPair() {
            int first = readInt();
            int second = readInt();
            return new IntIntPair(first, second);
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int readInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class D2_Helvetic_2016 {

	public static long MOD = 1000003;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		int n = in.nextInt();
		int c = in.nextInt();
		long[]p = new long[n + c];
		p[0] = 1;
		for(int i = 1; i < p.length; i++){
			p[i] = (p[i - 1]*(i % MOD) ) % MOD;
		}
		long result = 0;
		for(int i = 1;i <= n; i ++ ){
			long tmp = p[i + c - 1];
			tmp *= pow(p[i], MOD - 2);
			tmp %= MOD;
			tmp *= pow(p[c - 1] , MOD - 2);
			tmp %= MOD;
			result += tmp;
			result %= MOD;
		}
		out.println(result);
		out.close();
	}

	public static int[] KMP(String val) {
		int i = 0;
		int j = -1;
		int[] result = new int[val.length() + 1];
		result[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(j) != val.charAt(i)) {
				j = result[j];
			}
			j++;
			i++;
			result[i] = j;
		}
		return result;

	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	public static int digit(long n) {
		int result = 0;
		while (n > 0) {
			n /= 10;
			result++;
		}
		return result;
	}

	public static double dist(long a, long b, long x, long y) {
		double val = (b - a) * (b - a) + (x - y) * (x - y);
		val = Math.sqrt(val);
		double other = x * x + a * a;
		other = Math.sqrt(other);
		return val + other;

	}

	public static class Point implements Comparable<Point> {

		int x, y;

		public Point(int start, int end) {
			this.x = start;
			this.y = end;
		}

		@Override
		public int hashCode() {
			int hash = 5;
			hash = 47 * hash + this.x;
			hash = 47 * hash + this.y;
			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			final Point other = (Point) obj;
			if (this.x != other.x) {
				return false;
			}
			if (this.y != other.y) {
				return false;
			}
			return true;
		}

		@Override
		public int compareTo(Point o) {
			return Integer.compare(x, o.x);
		}
	}

	public static class FT {

		long[] data;

		FT(int n) {
			data = new long[n];
		}

		public void update(int index, long value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public long get(int index) {
			long result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

	public static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	public static long pow(long a, long b) {
		if (b == 0) {
			return 1;
		}
		if (b == 1) {
			return a;
		}
		long val = pow(a, b / 2);
		if (b % 2 == 0) {
			return val * val % MOD;
		} else {
			return val * (val * a % MOD) % MOD;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

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

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

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

		public String nextLine() {
			st = null;
			try {
				return br.readLine();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}
}


import java.util.Scanner;

public class TaskC {
	static String w0 = "What are you doing at the end of the world? Are you busy? Will you save us?";
	static String w1a = "What are you doing while sending \"";
	static String w1b = "\"? Are you busy? Will you send \"";
	static String w1c = "\"?";

	static long w1aLen = w1a.length();
	static long w1bLen = w1b.length();

	static String f1 = w1a+w0+w1b+w0+w1c;

	static long[] lens;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int q = sc.nextInt();
		int n;
		long k;
		lens = new long[54];
		for(int j = 0; j < 54; j++) {
			lens[j] = -1;
		}
		for(int i = 0; i < q; i++) {
			n = sc.nextInt();
			k = sc.nextLong();
			System.out.print(solve(n, k-1));
		}
		return;
	}

	public static char solve(int n, long k) {
		while(n >= 0) {
			if(k < 0 || k >= getLen(n)) {
				return '.';
			}
			if(n == 0) return w0.charAt((int)k);
			else if(n == 1) return f1.charAt((int)k);
			else {
				long nSub1Len = getLen(n-1);
				if(k < w1aLen)
				{
					return w1a.charAt((int)(k));
				}
				else if(k >= w1aLen && k < w1aLen + nSub1Len)
				{
					n--;
					k-=w1aLen;
				}
				else if(k >= w1aLen + nSub1Len && k < w1aLen + nSub1Len+ w1bLen)
				{
					return w1b.charAt((int)(k-w1aLen-nSub1Len));
				}
				else if(k >= w1aLen + nSub1Len+w1bLen && k < w1aLen + nSub1Len+w1bLen + nSub1Len)
				{
					n--;
					k-=(w1aLen + nSub1Len + w1bLen);
				}
				else
				{
					return w1c.charAt((int)(k-w1aLen-nSub1Len-w1bLen-nSub1Len));
				}
			}
		}
		return '.';
	}

	public static long getLen(int n) {
		if(n > 53) return getLen(53);
		if(lens[n] != -1) return lens[n];
		if(n == 0) {
			lens[n] = w0.length();
			return lens[n];
		} else {
			lens[n] = w1a.length() + getLen(n-1) + w1b.length() + getLen(n-1) + w1c.length();
			return lens[n];
		}
	}
}


import java.util.*;

public class Balance {

  public static final int MOD = 51123987;
  public static int[][] combos = null;

  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    in.nextInt();
    String s = in.next();
    int len = s.length();
    int half = (len+1)/2;
    int[][][][] groupCounts = new int[half+2][half+2][half+2][3];
    int[][][][][] prevAdd = new int[half+2][half+2][half+2][3][3];
    // [i][j][k][-] = # of subsequences such that there are 'i' groups of a, 'j' groups of b, 'k' groups of c
    // [-][-][-][0] = # of such groups where the rightmost group is type 'a', [1] type 'b', [2] type 'c'
    //

    for (int i = 0; i < len; ++i) {
      char val = s.charAt(i);
      for (int a = 0; a <= i && a <= half; ++a) {
        for (int b = 0; a+b <= i && b <= half; ++b) {
          for (int c = 0; a+b+c <= i && c <= half; ++c) {
            if (a+b+c == 0) {
              groupCounts[val=='a'?1:0][val=='b'?1:0][val=='c'?1:0][val-'a'] = 1;
              continue;
            }
            int newAdd;
            if (val == 'a') {
              newAdd = groupCounts[a][b][c][1] - prevAdd[a][b][c][1][0];
              groupCounts[a+1][b][c][0] = mod(groupCounts[a+1][b][c][0] + newAdd, MOD);
              prevAdd[a][b][c][1][0] += newAdd;

              newAdd = groupCounts[a][b][c][2] - prevAdd[a][b][c][2][0];
              groupCounts[a+1][b][c][0] = mod(groupCounts[a+1][b][c][0] + newAdd, MOD);
              prevAdd[a][b][c][2][0] += newAdd;
            } else if (val == 'b') {
              newAdd = groupCounts[a][b][c][0] - prevAdd[a][b][c][0][1];
              groupCounts[a][b+1][c][1] = mod(groupCounts[a][b+1][c][1] + newAdd, MOD);
              prevAdd[a][b][c][0][1] += newAdd;

              newAdd = groupCounts[a][b][c][2] - prevAdd[a][b][c][2][1];
              groupCounts[a][b+1][c][1] = mod(groupCounts[a][b+1][c][1] + newAdd, MOD);
              prevAdd[a][b][c][2][1] += newAdd;
            } else { // val == 'c'
              newAdd = groupCounts[a][b][c][0] - prevAdd[a][b][c][0][2];
              groupCounts[a][b][c+1][2] = mod(groupCounts[a][b][c+1][2] + newAdd, MOD);
              prevAdd[a][b][c][0][2] += newAdd;

              newAdd = groupCounts[a][b][c][1] - prevAdd[a][b][c][1][2];
              groupCounts[a][b][c+1][2] = mod(groupCounts[a][b][c+1][2] + newAdd, MOD);
              prevAdd[a][b][c][1][2] += newAdd;
            }
          }
        }
      }
    }
    long total = 0;
    for (int a = 0; a <= half; ++a) {
      for (int b = 0; b <= half; ++b) {
        for (int c = 0; a+b+c <= len && c <= half; ++c) {
          long calc = calculate(a, b, c, len) % MOD;
          total += groupCounts[a][b][c][0] * calc;
          total += groupCounts[a][b][c][1] * calc;
          total += groupCounts[a][b][c][2] * calc;
          total %= MOD;
        }
      }
    }
    System.out.println(total);
  }

  public static int[][] getCombinations(int n, int m) {
    if (combos != null)
      return combos;
    combos = new int[n+1][n+1];
    combos[0][0] = 1;
    for (int row = 1; row <= n; ++row) {
      combos[row][0] = 1;
      for (int col = 1; col <= row; ++col) {
        combos[row][col] = combos[row-1][col-1] + combos[row-1][col];
        if (combos[row][col] >= m)
          combos[row][col] -= m;
      }
    }
    return combos;
  }

  public static long calculate(int a, int b, int c, int total) {
    getCombinations(total, MOD);
    long ret = 1;
    int goal = total/3;
    //SPECIAL CASE: at least one is zero
    if (a == 0 || b == 0 || c == 0) {
      // the only way this is possible is if total <= 2
      // total == 2: 0,1,1 , 1,0,1, 1,1,0
      // total == 1: 0,0,1 , 0,1,0  1,0,0
      if (total > 2)
        return 0;
      int sum = a + b + c;
      if (sum == total)
        return 1;
      return 0;
    }
    if (total % 3 == 0) {
      // each group must have the same total;
      if (a > goal || b > goal || c > goal)
        return 0;
      ret *= combos[goal-1][goal-a];
      ret *= combos[goal-1][goal-b];
      ret %= MOD;
      ret *= combos[goal-1][goal-c];
      ret %= MOD;
    } else if (total % 3 == 1) {
      long retPartial = 0;
      // try goal,goal,goal+1
      if (a <= goal && b <= goal && c <= goal+1) {
        ret *= combos[goal-1][goal-a];
        ret *= combos[goal-1][goal-b];
        ret %= MOD;
        ret *= combos[goal][goal-c+1];
        retPartial += ret;
        ret = 1;
      }
      // try goal,goal+1,goal
      if (a <= goal && b <= goal+1 && c <= goal) {
        ret *= combos[goal-1][goal-a];
        ret *= combos[goal][goal-b+1];
        ret %= MOD;
        ret *= combos[goal-1][goal-c];
        retPartial += ret;
        ret = 1;
      }
      // try goal+1,goal,goal
      if (a <= goal+1 && b <= goal && c <= goal) {
        ret *= combos[goal][goal-a+1];
        ret *= combos[goal-1][goal-b];
        ret %= MOD;
        ret *= combos[goal-1][goal-c];
        retPartial += ret;
        ret = 1;
      }
      ret = retPartial % MOD;
    } else { // total % 3 == 2
      long retPartial = 0;
      // try goal,goal+1,goal+1
      if (a <= goal && b <= goal+1 && c <= goal+1) {
        ret *= combos[goal-1][goal-a];
        ret *= combos[goal][goal-b+1];
        ret %= MOD;
        ret *= combos[goal][goal-c+1];
        retPartial += ret;
        ret = 1;
      }
      // try goal+1,goal,goal+1
      if (a <= goal+1 && b <= goal && c <= goal+1) {
        ret *= combos[goal][goal-a+1];
        ret *= combos[goal-1][goal-b];
        ret %= MOD;
        ret *= combos[goal][goal-c+1];
        retPartial += ret;
        ret = 1;
      }
      // try goal+1,goal+1,goal
      if (a <= goal+1 && b <= goal+1 && c <= goal) {
        ret *= combos[goal][goal-a+1];
        ret *= combos[goal][goal-b+1];
        ret %= MOD;
        ret *= combos[goal-1][goal-c];
        retPartial += ret;
        ret = 1;
      }
      ret = retPartial % MOD;
    }
    return ret;
  }

  public static int mod(int a, int m) {
    if (a < 0)
      a += m;
    if (a >= m)
      a -= m;
    return a;
  }
}


import java.io.PrintWriter;
import java.util.Scanner;

public class C {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Subs subs = new Subs();
        subs.sol();
        subs.print();
    }

}

class Subs {

    Subs() {
        Scanner scr = new Scanner(System.in);
        String fs = scr.nextLine();
        String ft = scr.nextLine();
        s = fs.toCharArray();
        t = ft.toCharArray();
        scr.close();
    }

    void sol() {
        //long[][] dp = new long[s.length + 1][t.length + 1]; - memory limit
        long[] pred = new long[s.length+1];
        long[] curr = new long[s.length+1];

        ans = 0;
        long save;
        for (int j = 1; j <= t.length; j++){
            save = pred[0];
            for (int i = 1; i <= s.length; i++){

                /* de facto, but it's too slowly
                if (s[i-1] == t[j-1]) {
                    for (int k = 0; k < j; k++){
                        dp[i][j] = (dp[i][j] + dp[i-1][k]) % M;
                    }
                    dp[i][j] += 1;
                    ans = (ans + dp[i][j]) % M;
                */

                //dp[i][j] = dp[i][j-1];
                curr[i] = pred[i];
                if (s[i-1] == t[j-1]){
                    //dp[i][j] = (dp[i][j] + dp[i-1][j-1] + 1) % M;
                    curr[i] = (curr[i] + save + 1) % M;
                }
                save = pred[i];
                pred[i] = curr[i];
            }
        }
        for (int i = 1; i <= s.length; i++){
            //ans = (ans + dp[i][t.length]) % M;
            ans = (ans + curr[i]) % M;
        }
    }

    void print() {
        PrintWriter pw = new PrintWriter(System.out);
        pw.println(ans);
        pw.flush();
        pw.close();
    }

    long ans;
    char[] s;
    char[] t;
    static final int M = 1000000007;
}


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

public class CF1528E {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StreamTokenizer st = new StreamTokenizer(br);

    final int N = (int) (1e6 + 10);
    final int M = 998244353;

    long[] dp = new long[N], dp1 = new long[N], dp2 = new long[N];

    private long readLong() throws IOException {
        st.nextToken();
        return (long) st.nval;
    }

    private int readInt() throws IOException {
        st.nextToken();
        return (int) st.nval;
    }

    private String readString() throws Exception {
        st.nextToken();
        return st.sval;
    }

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

    long inv(long a) {
        return inv(a, M);
    }

    public long inv(long a, long mod) {
        long b = mod;
        long p = 1, q = 0;
        while (b > 0) {
            long c = a / b;
            long d;
            d = a;
            a = b;
            b = d % b;
            d = p;
            p = q;
            q = d - c * q;
        }
        return p < 0 ? p + mod : p;
    }

    long g(int n) {
        if (n < 0)
            return 0;
        long t = dp[n];
        long res = (t * (t + 1)) % M;
        res = (res * (t + 5)) % M;
        res = (res * inv(3)) % M;
        return (res + M) % M;
    }

    private void run() throws Exception {
        int n = readInt();
        dp[0] = dp1[0] = dp2[0] = 1;

        for (int i = 1; i <= n; i++) {
            dp[i] = ((dp[i - 1] + 1) * (dp[i - 1] + 2) / 2) % M;
            dp1[i] = dp[i] - dp[i - 1];
            dp2[i] = dp1[i] - dp1[i - 1];
        }
        long res = (g(n - 1) - g(n - 2)) % M;
        for (int i = 0; i < n; i++)
            res = (res + dp2[i] * dp1[n - 1 - i]) % M;
        res = (res + M) % M;
        System.out.println(res);
    }
}


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

public class Main {
    static Reader r = new Reader();
    static StringBuilder sb = new StringBuilder();
    static final int p = 1_000_000_007;

    public static ArrayList<Integer> primeList(int n){
        // return prime numbers less than or equal to n
        if(n==1) return new ArrayList<>();
        ArrayList<Integer> prime = new ArrayList<>();
        prime.add(2);
        if(n==2) return prime;

        boolean[] isPrime = new boolean[(n-1)/2];
        Arrays.fill(isPrime,true);
        for(int i=0;(2*i+3)*(2*i+3)<=n;i++){
            if(!isPrime[i]) continue;
            for(int j=((2*i+3)*(2*i+3)-3)/2;j<(n-1)/2;j+=(2*i+3))
                isPrime[j] = false;
        }
        for(int i=0;i<(n-1)/2;i++){
            if(isPrime[i]) prime.add(2*i+3);
        }
        return prime;
    }
    static int gcd(int n, int m){
        if(n==0) return (m>0)?m:-m;
        return gcd(m%n, n);
    }

    public static void main(String args[]) throws IOException {
        int n = r.readInt();
        ArrayList<Integer> prime = primeList((int)Math.sqrt(n));
        ArrayList<Integer>[] div = new ArrayList[n+1];
        int[] phi = new int[n+1];
        for(int i=1;i<=n;i++)
            div[i] = new ArrayList<>();
        for(int i=1;i<=n/2;i++){
            for(int j=2*i;j<=n;j+=i){
                div[j].add(i);
            }
        }
        for(int i=1;i<=n;i++){
            int m = i;
            int ans = m;
            for(int p:prime){
                if(p>Math.sqrt(m)) break;
                if(m%p!=0) continue;
                ans = (ans/p)*(p-1);
                while(m%p==0)
                    m/=p;
            }
            if(m>1) ans = (ans/m)*(m-1);
            phi[i] = ans;
        }
        long cnt = 0;
        for(int k=1;k<n;k++){
            for(int d:div[k]){
                cnt += (long) phi[k/d]*d*(n-k)/gcd(d,n-k);
                cnt %= p;
            }
        }
        System.out.println(cnt);
    }
}
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 String readLine() throws IOException {
        byte[] buf = new byte[1000000]; // line length
        int cnt = 0, c;
        while((c=read())!=-1){
            if(c=='\n'){
                if(cnt!=0) break;
                else continue;
            }
            buf[cnt++] = (byte)c;
        }
        return new String(buf, 0, cnt);
    }

    public int readInt() throws IOException {
        int ret = 0;
        byte c = read();
        while(c <= ' '){ c = read();}
        boolean neg = (c == '-');
        if(neg) c = read();
        do{
            ret = (ret<<3) + (ret<<1) + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        return neg ? -ret : ret;
    }

    public long readLong() throws IOException {
        long ret = 0;
        byte c = read();
        while(c <= ' '){ c = read();}
        boolean neg = (c == '-');
        if(neg) c = read();
        do{
            ret = (ret<<3) + (ret<<1) + c - '0';
        } while ((c = read()) >= '0' && c <= '9');
        return neg ? -ret : ret;
    }

    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();
    }
}


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;
        FastScanner in = new FastScanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            char[][] s = new char[][]{in.next().toCharArray(), in.next().toCharArray()};
            for (char[] c : s) {
                for (int i = 0; i < c.length; i++) {
                    if (c[i] == 'C') {
                        c[i] = 'B';
                    }
                }
            }
            int q = in.nextInt();

            int[][][] count = new int[2][][];
            int[][] sufA = new int[2][];
            for (int i = 0; i < 2; i++) {
                count[i] = count(s[i]);
                sufA[i] = sufA(s[i]);
            }
            int[][] info = new int[2][3];
            for (int i = 0; i < q; i++) {
                int l1 = in.nextInt() - 1, r1 = in.nextInt();
                int l2 = in.nextInt() - 1, r2 = in.nextInt();

                info[0][0] = count[0][0][r1] - count[0][0][l1];
                info[0][1] = count[0][1][r1] - count[0][1][l1];
                info[0][2] = Math.min(sufA[0][r1 - 1], r1 - l1);

                info[1][0] = count[1][0][r2] - count[1][0][l2];
                info[1][1] = count[1][1][r2] - count[1][1][l2];
                info[1][2] = Math.min(sufA[1][r2 - 1], r2 - l2);
                out.print(can(info[0], info[1]) ? '1' : '0');
            }
        }

        private boolean can(int[] a, int[] b) {
            a[0] -= a[2];
            b[0] -= b[2];
            if (a[2] < b[2]) {
                return false;
            }
            if (a[2] % 3 == b[2] % 3) {
                if (can2(a, b)) {
                    return true;
                }
            }
            a[2]--;
            a[1] += 2;

            a[0] += a[2] - b[2];
            return can2(a, b);
        }

        private boolean can2(int[] a, int[] b) {
            if (a[0] < 0 || a[1] < 0) {
                return false;
            }
            if (a[1] > b[1]) {
                return false;
            }
            if (a[1] % 2 != b[1] % 2) {
                return false;
            }
            if (b[1] > a[1] && (a[0] + a[1] == 0)) {
                return false;
            }
            return true;
        }

        private int[] sufA(char[] chars) {
            int[] a = new int[chars.length];
            for (int i = 0; i < chars.length; i++) {
                if (chars[i] == 'A') {
                    a[i] = (i == 0 ? 0 : a[i - 1]) + 1;
                } else {
                    a[i] = 0;
                }
            }
            return a;
        }

        private int[][] count(char[] chars) {
            int[][] a = new int[2][chars.length + 1];
            for (int i = 0; i < chars.length; i++) {
                a[0][i + 1] += a[0][i];
                a[1][i + 1] += a[1][i];
                a[chars[i] - 'A'][i + 1]++;
            }
            return a;
        }

    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

    }
}


import static java.lang.Double.parseDouble;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.System.exit;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class F {

	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer tok;

	static void solve() throws Exception {
		int n = nextInt();
		int p = nextInt();
		int q = nextInt();
		if (p >= n) {
			p = n - 1;
		}
		int c[] = new int[p + 1];
		c[0] = 1;
		for (int i = 1, val = 1, pow = 0; i <= p; i++) {
			int mul = n - i + 1;
			int shift = Integer.numberOfTrailingZeros(mul);
			val *= mul >> shift;
			pow += shift;
			mul = i;
			shift = Integer.numberOfTrailingZeros(mul);
			val *= BigInteger.valueOf(mul >> shift).modInverse(BigInteger.valueOf(0x100000000L)).intValue();
			pow -= shift;
			c[i] = pow >= 32 ? 0 : val << pow;
		}
		int ans = 0;
		for (int day = 1; day <= q; day++) {
			int cans = 0;
			for (int i = 0, pow = 1; i <= p; i++, pow *= day) {
				cans += c[i] * pow;
			}
			ans ^= day * cans;
		}
		out.print(ans & 0xffffffffL);
	}

	static int nextInt() throws IOException {
		return parseInt(next());
	}

	static long nextLong() throws IOException {
		return parseLong(next());
	}

	static double nextDouble() throws IOException {
		return parseDouble(next());
	}

	static String next() throws IOException {
		while (tok == null || !tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	public static void main(String[] args) {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(new OutputStreamWriter(System.out));
			solve();
			in.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			exit(1);
		}
	}
}


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

public class VK16_3F {

	static int B;
	static int P;
	static int Q;

	static long[] iFact;
	static long[] iFact2;

	public static void main0(String[] args) {
		System.out.println(Integer.toUnsignedString(inv(7)));
	}

	static int[] numF;
	static int[] numFP;
	static int[] iNumF;

	static int[] denF;
	static int[] denFP;
	static int[] iDenF;

	public static void main(String[] args) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter printer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		StringTokenizer inputData = new StringTokenizer(reader.readLine());

		B = Integer.parseInt(inputData.nextToken());
		P = Integer.parseInt(inputData.nextToken());
		P = Math.min(P, B);
		Q = Integer.parseInt(inputData.nextToken());

		numF = new int[P * 2 + 1];
		numF[0] = 1;
		numFP = new int[P * 2 + 1];

		iNumF = new int[P * 2 + 1];

		for (int i = 1; i <= P * 2; i++) {
			int cPow = Integer.numberOfTrailingZeros(B - i + 1);
			numF[i] = numF[i - 1] * ((B - i + 1) >> cPow);
			numFP[i] = numFP[i - 1] + cPow;
		}

		for (int i = 0; i <= P * 2; i++) {
			iNumF[i] = inv(numF[i]);
		}

		denF = new int[P * 2 + 1];
		denF[0] = 1;
		denFP = new int[P * 2 + 1];

		iDenF = new int[P * 2 + 1];

		for (int i = 1; i <= P * 2; i++) {
			int cPow = Integer.numberOfTrailingZeros(i);
			denF[i] = denF[i - 1] * (i >> cPow);
			denFP[i] = denFP[i - 1] + cPow;
		}

		for (int i = 0; i <= P * 2; i++) {
			iDenF[i] = inv(denF[i]);
		}

		int ans = 0;
		for (int n = 1; n <= Q; n++) {
			ans ^= n * calculate(n);
		}
		printer.println(Integer.toUnsignedString(ans));
		printer.close();
	}

	static int calculate(int n) {
		int cPow = 1;
		int sum = 0;
		int endI = Math.min(P, B - 1);
		for (int i = 0; i <= endI; i++) {
			sum += comb(B, i) * cPow;
			cPow *= n;
		}
		return sum;
	}

	static int comb(int n, int k) {
		int off = B - n;
		int cNumF = numF[k + off] * iNumF[off];
		int cNumP = numFP[k + off] - numFP[off];
		return (cNumF * iDenF[k]) << (cNumP - denFP[k]);
	}

	static int inv(int n) {
		int x = 1;
		x = x * (2 - x * n); /* Newton's method */
		x = x * (2 - x * n); /* 5 steps enough for 32 bits */
		x = x * (2 - x * n);
		x = x * (2 - x * n);
		x = x * (2 - x * n);
		return x;
	}
}


//package educational.round11;
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 EE {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni();
		int mod = 1000000007;
		long ret = 2L*m;
		long f = m;
		for(int i = 2;i <= n;i++){
			ret = ret * (2*m-1) + f;
			f = f * m;
			ret %= mod;
			f %= mod;
		}
		out.println(ret);
	}

	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 EE().run(); }

	private byte[] inbuf = new byte[1024];
	private 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.PrintWriter;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.io.InputStream;

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

    static class TaskC {
        public static boolean angle(TaskC.Point a, TaskC.Point b) {
            double amag = a.mag();
            double bmag = b.mag();
            double abmag = a.v * b.v + a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z;
            double angle = Math.toDegrees(Math.acos(abmag / (amag * bmag)));
            if (angle < 90) {
                return true;
            }
            return false;
        }

        public void solve(int testNumber, FastScanner in, PrintWriter out) {
            int n = in.nextInt();
            if (n > 11) {
                out.println("0");
            } else {
                HashSet<Integer> good = new HashSet<Integer>();
                ArrayList<TaskC.Point> arr = new ArrayList<>();
                for (int i = 0; i < n; i++) {
                    int a = in.nextInt();
                    int b = in.nextInt();
                    int c = in.nextInt();
                    int d = in.nextInt();
                    int e = in.nextInt();
                    TaskC.Point p = new TaskC.Point(a, b, c, d, e);
                    arr.add(p);
                }
                for (int i = 0; i < n; i++) {
                    boolean b = true;
                    for (int j = 0; j < n; j++) {
                        for (int k = 0; k < n; k++) {
                            if (i != j && i != k && j != k) {
                                TaskC.Point one = arr.get(j);
                                TaskC.Point two = arr.get(k);
                                TaskC.Point three = arr.get(i);
                                TaskC.Point lol2 = new TaskC.Point(one.v - three.v, one.w - three.w, one.x - three.x, one.y - three.y, one.z - three.z);
                                TaskC.Point lol1 = new TaskC.Point(two.v - three.v, two.w - three.w, two.x - three.x, two.y - three.y, two.z - three.z);
                                if (angle(lol1, lol2)) {
                                    b = false;
                                }
                            }
                        }
                    }
                    if (b) {
                        good.add(i + 1);
                    }
                }
                if (good.size() == 0) {
                    out.println("0");
                } else {
                    out.println(good.size());
                    for (int i : good) {
                        out.println(i);
                    }
                }
            }
        }

        public static class Point {
            int v;
            int w;
            int x;
            int y;
            int z;

            public Point(int a, int b, int c, int d, int e) {
                v = a;
                w = b;
                x = c;
                y = d;
                z = e;
            }

            public double mag() {
                return Math.sqrt(v * v + w * w + x * x + y * y + z * z);
            }

        }

    }

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

        public FastScanner(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.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.util.Set;
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
 *
 * @author Yogesh Kumar a.k.a DREAMPLAY
 */
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);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
//        System.out.println(Math.toDegrees(Math.acos(0.5)));
            int n = in.nextInt();
            if (n >= 100) {
                out.print(0);
            } else {
                int[] a = new int[105];
                int[] b = new int[105];
                int[] c = new int[105];
                int[] d = new int[105];
                int[] e = new int[105];
                for (int i = 1; i <= n; i++) {
                    a[i] = in.nextInt();
                    b[i] = in.nextInt();
                    c[i] = in.nextInt();
                    d[i] = in.nextInt();
                    e[i] = in.nextInt();
                }

                Set<Integer> bad = new HashSet<>();

                for (int i = 1; i <= n; i++) {
                    for (int j = 1; j <= n; j++) {
                        for (int k = 1; k <= n; k++) {
                            if (i == j || j == k || k == i) {
                                continue;
                            }

                            long ax = a[j] - a[i];
                            long bx = b[j] - b[i];
                            long cx = c[j] - c[i];
                            long dx = d[j] - d[i];
                            long ex = e[j] - e[i];

                            long ay = a[k] - a[i];
                            long by = b[k] - b[i];
                            long cy = c[k] - c[i];
                            long dy = d[k] - d[i];
                            long ey = e[k] - e[i];

                            double val = ax * ay + bx * by + cx * cy + dx * dy + ex * ey;
                            long m1 = ax * ax + bx * bx + cx * cx + dx * dx + ex * ex;
                            long m2 = ay * ay + by * by + cy * cy + dy * dy + ey * ey;
                            val = val / Math.sqrt(m1);
                            val = val / Math.sqrt(m2);
                            if (Math.toDegrees(Math.acos(val)) + 0.000000001 < 90) {
                                bad.add(i);
                            }
                        }
                    }
                }

                out.println(n - bad.size());

                for (int i = 1; i <= n; i++) {
                    if (!bad.contains(i)) {
                        out.println(i);
                    }
                }
            }
        }

    }

    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.util.*;
import java.io.*;
/*
TASK: fivedimpoints
LANG: JAVA
 */

public class fivedimpoints{
    static int n;
    static int[][] coord;
    static long[][][] vect;
    static boolean[] bad;

    public static void main(String[] args) throws IOException{
        FastScanner in = new FastScanner(System.in);
        n = in.nextInt();
        if(n > 11){
            System.out.println(0);
            return;
        }
        coord = new int[n][5];
        vect = new long[n][n][5];
        bad = new boolean[n];
        for(int i = 0;i <n; i++){
            for(int j = 0;j < 5;j++){
                coord[i][j] = in.nextInt();
            }
        }
        for(int i = 0;i < n; i++){
            for(int j = 0;j < n; j++){
                for(int k = 0; k < 5; k++){
                    vect[i][j][k] = coord[j][k] - coord[i][k];
                }
            }
        }
        int count = n;
        long prod;
        for(int i = 0;i < n; i++){
            for(int j = 0;j < n; j++){
                if(j != i){
                    for(int k = 0; k < n; k++){
                        if(k != j && k != i){
                            prod = 0;
                            for(int m = 0; m < 5; m++){
                                prod += vect[j][i][m]*vect[k][i][m];
                            }
                            if(prod > 0 && !bad[i]){
                                bad[i] = true;
                                count--;
                            }
                        }
                    }
                }
            }
        }
        System.out.println(count);
        for(int i = 0;i < n; i++){
            if(!bad[i]){
                System.out.println(i+1);
            }
        }
    }
}
class FastScanner{
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public FastScanner(InputStream stream) {
        this.stream = stream;
    }
    int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0) return -1;
        }
        return buf[curChar++];
    }

    boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    boolean isEndline(int c) {
        return c == '\n' || c == '\r' || c == -1;
    }

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

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

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

    public String next() {
        int c = read();
        while (isSpaceChar(c)) c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public String nextLine() {
        int c = read();
        while (isEndline(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isEndline(c));
        return res.toString();
    }
}


import java.io.*;
import java.util.*;
import java.math.*;
import java.lang.*;

import static java.lang.Math.*;

public class Main implements Runnable
{
	static class InputReader
	{
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;
		private BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

		public InputReader(InputStream stream)
		{
			this.stream = stream;
		}

		public int read()
		{
			if (numChars==-1)
				throw new InputMismatchException();

			if (curChar >= numChars)
			{
				curChar = 0;
				try
				{
					numChars = stream.read(buf);
				}
				catch (IOException e)
				{
					throw new InputMismatchException();
				}

				if(numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine()
		{
			String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
		}
		public int nextInt()
		{
			int c = read();

			while(isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-')
			{
				sgn = -1;
				c = read();
			}

			int res = 0;
			do
			{
				if(c<'0'||c>'9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));

			return res * sgn;
		}

		public long nextLong()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			long res = 0;

			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
				return res * sgn;
		}

		public double nextDouble()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			double res = 0;
			while (!isSpaceChar(c) && c != '.')
			{
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, nextInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			if (c == '.')
			{
				c = read();
				double m = 1;
				while (!isSpaceChar(c))
				{
					if (c == 'e' || c == 'E')
						return res * Math.pow(10, nextInt());
					if (c < '0' || c > '9')
						throw new InputMismatchException();
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}
			return res * sgn;
		}

		public String readString()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			}
			while (!isSpaceChar(c));

			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public String next()
		{
			return readString();
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}
	}

	public static void main(String args[]) throws Exception
	{
		new Thread(null, new Main(),"Main",1<<26).start();
	}

	int findAngle(Point p1, Point p2)
    {
            return p1.a * p2.a + p1.b * p2.b + p1.c * p2.c + p1.d * p2.d + p1.e * p2.e;
    }

	Point makeVector(Point p1, Point p2)
    {
        return  new Point(p1.a - p2.a, p1.b - p2.b, p1.c - p2.c, p1.d - p2.d, p1.e - p2.e);
    }

    public void run()
	{
		InputReader sc = new InputReader(System.in);
		PrintWriter w = new PrintWriter(System.out);
		int n = sc.nextInt();

                if(n > 20)
                {
                    w.print("0");
                    w.close();
                    return;
                }

                Point point[] = new Point[n];
                for(int i = 0; i < n; ++i)
                {
                    point[i] = new Point(sc.nextInt(), sc.nextInt(), sc.nextInt(), sc.nextInt(), sc.nextInt());
                }

                ArrayList<Integer> ans = new ArrayList<>();
                for(int i = 0; i < n; ++i)
                {
                    int flag = 0;
                    midloop:for(int j = 0; j < n; ++j)
                    {
                        for(int k= 0; k< n && j != i; ++k)
                        {
                            if(k != j && k != i)
                            {
                                Point p1 = makeVector(point[i], point[j]);
                                Point p2 = makeVector(point[i], point[k]);
                                int value = findAngle(p1, p2);
                                if(value > 0)
                                {
                                    flag = 1;
                                    break midloop;
                                }
                            }
                        }
                    }
                    if(flag == 0)
                        ans.add(i);
                }

                w.println(ans.size());
                for(int i = 0; i < ans.size(); ++i)
                {
                    w.println((ans.get(i) + 1));
                }
		w.close();
	}
}
class Point
{
    int a,b,c,d,e;
    Point(int a, int b, int c, int d, int e)
    {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
        this.e = e;
    }
}


import java.util.ArrayList;
import java.util.Scanner;

public class P851C
{
	static double eps = 1e-9;
	public static void main(String[] args)
	{
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		if (n > 11)
		{
			System.out.println(0);
			return;
		}
		int[][] arr = new int[n][5];
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < 5; j++)
			{
				arr[i][j] = scan.nextInt();
			}
		}
		ArrayList<Integer> list = new ArrayList<>();
		for (int i = 0; i < n; i++)
		{
			boolean good = true;
			Loop:
			for (int j = 0; j < n; j++)
			{
				if (j == i)
					continue;
				for (int k = j+1; k < n; k++)
				{
					if (k == i)
						continue;
					Vector v1 = new Vector(arr[i], arr[j]);
					Vector v2 = new Vector(arr[i], arr[k]);
					double angle = Math.acos(v1.prod(v2)/(v1.mag()*v2.mag()));
					if (angle < Math.PI/2-eps)
					{
						good = false;
						break Loop;
					}
				}
			}
			if (good)
				list.add(i+1);
		}
		System.out.println(list.size());
		for (int i : list)
			System.out.println(i);
	}
	static class Vector
	{
		int[] arr = new int[5];
		Vector(int[] a, int[] b)
		{
			for (int i = 0; i < 5; i++)
			{
				arr[i] = b[i]-a[i];
			}
		}
		double mag()
		{
			double sum = 0;
			for (int i = 0; i < arr.length; i++)
			{
				sum += arr[i]*arr[i];
			}
			return Math.sqrt(sum);
		}
		int prod(Vector v)
		{
			int sum = 0;
			for (int i = 0; i < arr.length; i++)
			{
				sum += arr[i]*v.arr[i];
			}
			return sum;
		}
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;
import java.util.ArrayList;

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

    static class TaskC {
        public void solve(int testNumber, Scanner in, PrintWriter out) {
            int n = in.nextInt();
            if (n > 40) {
                out.println(0);
                return;
            } else {
                final ArrayList<TaskC.Point> points = new ArrayList<>();
                for (int i = 0; i < n; ++i) {
                    int a, b, c, d, e;
                    a = in.nextInt();
                    b = in.nextInt();
                    c = in.nextInt();
                    d = in.nextInt();
                    e = in.nextInt();
                    points.add(new TaskC.Point(a, b, c, d, e));
                }
                if (n < 3) {
                    out.println(n);
                    for (int i = 1; i <= n; ++i) {
                        out.println(i);
                    }
                    return;
                }
                ArrayList<Integer> result = new ArrayList<>();
                for (int center = 0; center < n; ++center) {
                    boolean find = false;
                    for (int a = 0; a < n; ++a)
                        if (a != center) {
                            for (int b = 0; b < n; ++b)
                                if (b != center && b != a) {
                                    TaskC.Point A = points.get(a).minus(points.get(center));
                                    TaskC.Point B = points.get(b).minus(points.get(center));
                                    if (A.dot(B)) {
                                        find = true;
                                        break;
                                    }
                                }
                            if (find) break;
                        }
                    if (!find) result.add(center + 1);
                }
                out.println(result.size());
                for (int id : result) {
                    out.println(id);
                }
            }
        }

        static class Point {
            long a;
            long b;
            long c;
            long d;
            long e;

            public Point(long a, long b, long c, long d, long e) {
                this.a = a;
                this.b = b;
                this.c = c;
                this.d = d;
                this.e = e;
            }

            boolean dot(final TaskC.Point rhs) {
                return a * rhs.a + b * rhs.b + c * rhs.c + d * rhs.d + e * rhs.e > 0;
            }

            TaskC.Point minus(final TaskC.Point rhs) {
                return new TaskC.Point(a - rhs.a, b - rhs.b, c - rhs.c, d - rhs.d, e - rhs.e);
            }

        }

    }
}


import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;

/**
 * Created by Pranav ps on 04-09-2017.
 */
public class wedss {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        if(n <= 11){
            long[][] points = new long[n][5];

            for(int i = 0 ; i < n; i++){
                for (int j = 0; j < 5; j++) {
                    points[i][j] = sc.nextLong();
                }
            }

            long[][][] vectors = new long[n][n][5];
            for(int i = 0; i < n; i++){
                for(int j = 0; j < n; j++){
                    for (int k = 0; k < 5; k++) {
                        vectors[i][j][k] = points[j][k] - points[i][k];
                    }
                }
            }

            HashSet<Integer> list = new HashSet<>();

            for(int i = 0; i < n; i++){
                boolean flag = false;
                for (int j = 0; j < n; j++) {
                    for (int k = 0; k < n; k++) {
                        if(!equal(vectors[i][j],vectors[i][k]) && dot(vectors[i][j],vectors[i][k])){
                            list.add(i+1);
                            flag = true;
                            break;
                        }
                    }
                    if(flag)
                        break;
                }
            }

            System.out.println(n - list.size());
            for(int i = 0; i < n; i++){
                if(!list.contains(i+1))
                    System.out.println(i+1);
            }
        }
        else{
            System.out.println(0);
        }
    }
    private static boolean equal(long[] a, long[] b){
        boolean res = true;
        for(int i = 0 ; i < 5; i++){
            res &= a[i]==b[i];
        }
        return res;
    }
    private static boolean dot(long[] a, long[] b){
        long res = 0;
        for(int i = 0 ; i < 5; i++){
            res += a[i]*b[i];
        }

        return res>0;
    }
}


import java.io.*;
import java.math.*;
import java.util.*;
public class Main{

  public static long sq(long a){
    return a*a;
  }
  public static long distSq(long ax, long ay, long bx, long by){
    return sq(ax-bx)+sq(ay-by);
  }

  public static class Point{
    long x1;
    long x2;
    long x3;
    long x4;
    long x5;

    public Point(long x1, long x2, long x3, long x4, long x5){
      this.x1 = x1;
      this.x2 = x2;
      this.x3 = x3;
      this.x4 = x4;
      this.x5 = x5;
    }

    private static long sq(long x){
      return x*x;
    }
    public long lenSq(){
      return sq(x1)+sq(x2)+sq(x3)+sq(x4)+sq(x5);
    }

    public long prod(Point other){
      return this.x1*other.x1 + this.x2*other.x2 + this.x3*other.x3 + this.x4*other.x4 + this.x5*other.x5;
    }

    public Point sub(Point other){
      return new Point(this.x1-other.x1,this.x2-other.x2,this.x3-other.x3,this.x4-other.x4,this.x5-other.x5);
    }

  }

  public static boolean check(ArrayList<Point> points, int i){
    Point ith = points.get(i);
    int n = points.size();
    for(int j=0; j<n; ++j){
      if(j == i){
        continue;
      }
      for(int k=0; k<n; k++){
        if(k == i || k == j){
            continue;
        }

        Point x = points.get(j).sub(ith);
        Point y = points.get(k).sub(ith);
        if(x.prod(y) > 0){
          return false;
        }
      }
    }
    return true;
  }

  public static void main(String[] args){
    InputReader reader = new InputReader(System.in);
    PrintWriter pw = new PrintWriter(System.out);
    int n = reader.nextInt();
    if(n > 11){
      pw.printf("0\n");
      pw.flush();
      pw.close();
      return;
    }
    ArrayList<Point> points = new ArrayList<Point>(n);
    for(int i=0; i<n; ++i){
      points.add(new Point(reader.nextLong(), reader.nextLong(), reader.nextLong(), reader.nextLong(), reader.nextLong()));
    }

    ArrayList<Integer> ret = new ArrayList<Integer>(11);
    for(int i=0; i<n; ++i){
      if(check(points,i)){
        ret.add(i+1);
      }
    }

    pw.printf("%d\n", ret.size());
    for(Integer x : ret){
      pw.printf("%d\n", x);
    }
    pw.flush();
    pw.close();
  }

  public static class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    public InputReader (InputStream stream){
      reader = new BufferedReader(new InputStreamReader(stream));
    }

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

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

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

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

    public BigInteger nextBigInteger(){
      return new BigInteger(next());
    }

    public String nextLine(){
      String line = "";
      try{
        while(line.equals("")){
          line = reader.readLine();
        }
      } catch(IOException ioe){
        throw new RuntimeException(ioe);
      }
      return line;
    }
  }

}