import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.ObjectInputStream.GetField;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class Global14 {
	static PrintWriter out;
	static Scanner sc;
	static ArrayList<int[]>q,w,x;
	static ArrayList<Integer>adj[];
	static HashSet<Integer>primesH;
	static boolean prime[];
	//static ArrayList<Integer>a;
	static HashSet<Long>tmp;
	static int[][][]dist;
	static boolean[]v;
	static int[]a,b,c,d;
	static Boolean[][]dp;
	static char[][]mp;
	static int A,B,n,m,h,ans,sum;
	//static String a,b;
	static long oo=(long)1e9+7;
	public static void main(String[]args) throws IOException {
		sc=new Scanner(System.in);
		out=new PrintWriter(System.out);
		//A();
		//B();
		//C();
		//D();
		E();
		//F();
		//G();
		out.close();
	}
	  private static void A() throws IOException {
		  int t=ni();
		  while(t-->0) {
				int n=ni(),w=ni();
				a=nai(n);
				int sum=0;
				for(int i=0;i<n;i++)sum+=a[i];
				if(sum==w) {ol("NO");continue;}
				if(sum<w) {
					ol("YES");
					disp2(a);continue;
				}
				Arrays.sort(a);
				int cur=0;
				for(int i=n-1;i>=0;i--) {
					if(cur==w) {
						int tmp=a[i+1];
						a[i+1]=a[i];
						a[i]=tmp;
						break;
					}
					cur+=a[i];
				}
				ol("YES");
				disp2(a);

		  }

	   }
		static void B() throws IOException {
			int t=ni();
			while(t-->0) {
				long n=nl();
				if(n%2==0) {
				n/=2;
				int sq=(int)Math.sqrt(n);
				if(sq*sq==n&&sq!=0) {
					ol("YES");continue;
				}
				}
				if(n%2==0) {
				n/=2;
				 int sq=(int)Math.sqrt(n);
				if(sq*sq==n&&sq!=0) {
					ol("YES");continue;
				}
				}
				ol("NO");
			}
			}

		static void C() throws IOException{
			 int t=ni();
			 while(t-->0) {
				int n=ni(),m=ni(),x=ni();
				int[][]a=new int[n][2];
				int mx=0;
				for(int i=0;i<n;i++) {
					a[i][0]=ni();
					a[i][1]=i;
					mx=Math.max(mx, a[i][0]);
				}
				Arrays.sort(a,(u,v)->u[0]-v[0]);
				PriorityQueue<int[]>vals=new PriorityQueue<int[]>((u,v)->u[0]-v[0]);
				int[]ans=new int[n];
				//int grp=1;
				vals.add(new int[] {a[0][0],1});
				ans[a[0][1]]=1;
				for(int i=1;i<n;i++) {
					if(vals.size()<m) {
						ans[a[i][1]]=vals.size()+1;
						vals.add(new int[] {a[i][0],vals.size()+1});
						mx=Math.max(mx, a[i][0]);
					}else {
						int[]p=vals.poll();
						vals.add(new int[] {p[0]+a[i][0],p[1]});
						ans[a[i][1]]=p[1];
						mx=Math.max(mx, a[i][0]+p[0]);
					}
				}
				if(mx-vals.peek()[0]>x)ol("NO");
				else {

					ol("YES");
					for(int i=0;i<n;i++) {
						out.print(ans[i]+" ");
					}
					ol("");
				}

			 }
		}
		private static Boolean dp(int i, int j) {
			if(j>sum/2)return false;
			if(i==x.size()) {
				return sum/2==j;
			}
			if(dp[i][j]!=null)return dp[i][j];

			return dp[i][j]=dp(i+1,j+x.get(i)[0])||dp(i+1,j);
		}
		static boolean isPrime(long n) {
			if(n==2)return true;
			if(n<2||n%2==0)return false;

			for(long i=3L;i*i<n;i+=2l) {
				long rem=(n%i);
				if(rem==0)return false;
			}
			return true;
		}
		static void D() throws IOException {
			int t=ni();
			while(t-->0) {
				int n=ni(),l=ni(),r=ni();
				int[]occ1=new int[n+1];
				a=nai(n);
				for(int i=0;i<l;i++) {
					occ1[a[i]]++;
				}
				int[]occ2=new int[n+1];
				for(int i=l;i<n;i++) {
					occ2[a[i]]++;
				}
				int base=Math.abs((n/2)-l);
				int tk=0;
				int[]lrg=l>r?occ1:occ2;
				int[]sml=l<=r?occ1:occ2;
				for(int i=0;i<=n&&tk<base;i++) {
					int rem=base-tk;
					int taken=Math.min(rem,
							Math.max(0,(lrg[i]-sml[i])/2));
					lrg[i]-=taken;
					sml[i]+=taken;
					tk+=taken;
				}
				for(int i=0;i<n&&tk<base;i++) {
					if(lrg[i]<=sml[i])continue;
					lrg[i]--;
					sml[i]++;
					tk++;
				}
				int c1=0,c2=0;
				for(int i=0;i<=n;i++) {
					if(lrg[i]>sml[i]) {
						if(c1<0) {
							int diff=Math.min(-c1, -sml[i]+lrg[i]);
							lrg[i]-=diff;
							c1+=diff;
						}
						int nd=lrg[i]-sml[i];
						c2-=nd;
						base+=nd;
						sml[i]=lrg[i];
					}else if(lrg[i]<sml[i]) {
						if(c2<0) {
							int diff=Math.min(-c2, sml[i]-lrg[i]);
							sml[i]-=diff;
							c2+=diff;
						}
						int nd=-lrg[i]+sml[i];
						base+=nd;
						c1-=nd;
						lrg[i]=sml[i];
					}
				}
				ol(base);
			}
		}
		private static int bfs(int i, int j,int k) {
			boolean [][]vis=new boolean[dist.length][dist[0].length];
			Queue<int[]>q=new LinkedList<int[]>();
			int mn=Integer.MAX_VALUE;
			q.add(new int[] {i,j,0,0});
			int[]dx=new int[] {-1,1,0,0};
			int[]dy=new int[] {0,0,1,-1};
			while(!q.isEmpty()) {
				int []x=q.poll();
				vis[x[0]][x[1]]=true;
				int c=x[2];
				if(c>k/2)continue;
				if(c>0&&k%c==0&&(k/c)%2==0) {
					mn=Math.min(mn,x[3]*k/c );
				}
				for(int a=0;a<4;a++) {
					int nx=x[0]+dx[a];
					int ny=x[1]+dy[a];
					if(valid(nx,ny)&&!vis[nx][ny]) {
						q.add(new int[] {nx,ny,c+1,x[3]+dist[x[0]][x[1]][a]});
					}
				}

			}
			return mn;
		}
		private static boolean valid(int nx, int ny) {
			return nx>=0&&nx<dist.length&&ny>=0&&ny<dist[0].length;
		}
		static int gcd (int a, int b) {
		    return b==0?a:gcd (b, a % b);
		}

	static void E() throws IOException {
		int t=1;
		while(t-->0) {
			int n=ni();
			long oo=nl();
			long fc[]=new long[n+1];
			fc[0]=fc[1]=1l;
			long []pow2=new long[n+1];
			pow2[0]=1l;
			for(int i=1;i<pow2.length;i++) {
				pow2[i]=(pow2[i-1]*2l)%oo;
			}
			for(int i=2;i<fc.length;i++) {
				fc[i]=fc[i-1]*1l*i%oo;
			}

			long ncr[][]=new long[n+1][n+1];
			for(int i=0;i<=n;i++) {
				for(int j=0;j<=i;j++) {
					ncr[i][j]=i==0||j==0?1l:(ncr[i-1][j-1]+ncr[i-1][j])%oo;
				}
			}
			long ans=0;
			long dp[][]=new long[n+2][n+2];
			dp[0][0]=1;
			for(int i=0;i<n;i++) {
				for(int j=0;j<=i;j++) {
					for(int k=1;i+k<=n;k++) {
						dp[i+k+1][j+k]+=((dp[i][j]*pow2[k-1]%oo)*ncr[j+k][k])%oo;
						//dp[i+k+1][j+k]%=oo;
					}
				}
			}
			for(int i=0;i<=n;i++) {
				ans=(ans+dp[n+1][i])%oo;
			}
			ol(""+ans);
			//ol(""+pow2[3]);
		}

	}

	static void F() throws IOException {
		int t=ni();
		while(t-->0) {

		}
	}
	static void CC() throws IOException {
		for(int kk=2;kk<21;kk++) {
			ol(kk+"   -------");
		int n=kk;
		int k=n-2;
		int msk=1<<k;
		int[]a=new int[k];
		for(int i=0;i<a.length;i++)a[i]=i+2;
		int mx=1;
		int ms=0;
		for(int i=1;i<msk;i++) {
			long prod=1;
			int cnt=0;
			for(int j=0;j<a.length;j++) {
				if(((i>>j)&1)!=0) {
					prod*=a[j];
					cnt++;
				}
			}
			if(cnt>=mx&&prod%n==1) {
				mx=cnt;
				ms=i;
			}

		}
		ol(mx==1?mx:mx+1);
		out.print(1+" ");
		long pr=1;
		for(int j=0;j<a.length;j++) {
			if(((ms>>j)&1)!=0) {
				out.print(a[j]+" ");
				pr*=a[j];
			}
		}
		ol("");
		ol("Prod: "+pr);
		ol(n+"*"+((pr-1)/n)+" + "+1);
		}
	}
	static int ni() throws IOException {
		return sc.nextInt();
	}
	static double nd() throws IOException {
		return sc.nextDouble();
	}
	static long nl() throws IOException {
		return  sc.nextLong();
	}
	static String ns() throws IOException {
		return sc.next();
	}
	static int[] nai(int n) throws IOException {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = sc.nextInt();
		return a;
	}
	static long[] nal(int n) throws IOException {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = sc.nextLong();
		return a;
	}
	static int[][] nmi(int n,int m) throws IOException{
		int[][]a=new int[n][m];
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				a[i][j]=sc.nextInt();
			}
		}
		return a;
	}

	static long[][] nml(int n,int m) throws IOException{
		long[][]a=new long[n][m];
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {
				a[i][j]=sc.nextLong();
			}
		}
		return a;
	}
	static void o(String x) {
		out.print(x);
	}
	static void ol(String x) {
		out.println(x);
	}
	static void ol(int x) {
		out.println(x);
	}
	static void disp1(int []a) {
		for(int i=0;i<a.length;i++) {
			out.print(a[i]+" ");
		}
		out.println();
	}
	static void disp2(int []a) {
		for(int i=a.length-1;i>=0;i--) {
			out.print(a[i]+" ");
		}
		out.println();
	}
	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}
		public boolean hasNext() {return st.hasMoreTokens();}
		public int nextInt() throws IOException {return Integer.parseInt(next());}

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

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

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

		public boolean ready() throws IOException {return br.ready(); }

	}
}


import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;

public class Main{

    static long MOD = 1_000_000_007L;
    //static long MOD = 998_244_353L;
    //static long MOD = 1_000_000_033L;
    static long inv2 = (MOD + 1) / 2;

    static int[][] dir = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
    static long lMax = 0x3f3f3f3f3f3f3f3fL;
    static int iMax = 0x3f3f3f3f;
    static HashMap <Long, Long> memo = new HashMap();
    static MyScanner sc = new MyScanner();
    //static ArrayList <Integer> primes;

    static int nn = 300000;
    static long[] pow2;
    static long [] fac;
    static long [] pow;
    static long [] inv;
    static long [] facInv;
    static int[] base;
    static int[] numOfDiffDiv;
    static int[] numOfDiv;
    static ArrayList <Integer> primes;
    //static int[] primes;
    static int ptr = 0;
    static boolean[] isPrime;

    //-----------PrintWriter for faster output---------------------------------
    public static PrintWriter out;
    public static void main(String[] args) {
        out = new PrintWriter(new BufferedOutputStream(System.out));
        // Start writing your solution here. -------------------------------------

        /*fac = new long[nn + 1];
        fac[1] = 1;
        for(int i = 2; i <= nn; i++)
            fac[i] = fac[i - 1] * i % MOD;*/

        /*pow2 = new long[nn + 1];
        pow2[0] = 1L;
        for(int i = 1; i <= nn; i++)
            pow2[i] = pow2[i - 1] * 2L;*/

        /*inv = new long[nn + 1];
        inv[1] = 1;
        for (int i = 2; i <= nn; ++i)
            inv[i] = (MOD - MOD / i) * inv[(int)(MOD % i)] % MOD;*/

        /*facInv = new long[nn + 1];
        facInv[0] = facInv[1] = 1;
        for (int i = 2; i <= nn; ++i)
            facInv[i] = facInv[i - 1] * inv[i] % MOD;*/

        /*numOfDiffDiv = new int[nn + 1];
        for(int i = 2; i <= nn; i++)
            if(numOfDiffDiv[i] == 0)
                for(int j = i; j <= nn; j += i)
                    numOfDiv[j] ++;*/

        /*numOfDiv = new int[nn + 1];
        numOfDiv[1] = 1;
        for(int i = 2; i <= nn; i++) {
            for(int j = 2; j * j <= i; j++) {
                if(i % j == 0) {
                    numOfDiv[i] = numOfDiv[i / j] + 1;
                    break;
                }
            }
        }*/

        //primes = sieveOfEratosthenes(100001);

        /*
        int t = 1;
        //t = sc.ni();
        while(t-- > 0) {
            //boolean res = solve();
            //out.println(res ? "YES" : "NO");
            long res = solve();
            out.println(res);
        }*/

        int t = 1, tt = 0;
        t = sc.ni();
        for(int i = 1; i <40000; i++) squares.add(i * i);
        while(tt++ < t) {
            boolean res = solve();
            //out.println("Case #" + tt + ": " + res);
            //out.println(res ? "YES" : "NO");
        }
        out.close();
    }
    static HashSet <Integer> squares = new HashSet();

    static boolean solve() {
        /*String s = sc.nextLine();
        char[] c = s.toCharArray();
        int n = c.length;*/
        //int n = sc.ni();
        //long[] a =  new long[n];
        //for(int i = 0; i < n; i++) a[i] = sc.nl();
        long res = 0;
        int n = sc.ni();
        long m = sc.nl();
        long[][][] dp = new long[2][n + 3][n + 3];
        long[][][] dp2 = new long[2][n + 3][n + 3];
        dp[0][2][1] = dp[1][2][2] = dp2[0][1][1] = 1L;
        for(int i = 3; i <= n; i++) {
            long[][] bef = dp[0];
            long[][] aft = dp[1];
            long[][] nbef = new long[n + 3][n + 3];
            long[][] naft = new long[n + 3][n + 3];
            for(int len = 1; len <= i; len++) {
                for(int ind = 1; ind <= len; ind++) {
                    nbef[len + 1][1] += bef[len][ind];
                    nbef[len + 1][ind + 1] -= bef[len][ind];
                    naft[len + 1][ind + 1] += bef[len][ind];
                    //naft[len + 1][len + 2] -= bef[len][ind];
                    naft[len + 1][ind + 1] += aft[len][ind];
                    //naft[len + 1][len + 2] -= aft[len][ind];
                    nbef[len + 1][1] += dp2[0][len][ind] + dp2[1][len][ind];
                    //nbef[len + 1][len + 2] -= dp2[0][len][ind] + dp2[1][len][ind];
                }
            }
            for(int len = 1; len <= i; len++) {
                for(int ind = 1; ind <= len; ind ++) {
                    nbef[len][ind] = (nbef[len][ind] + nbef[len][ind - 1] + 100L * m) % m;
                    naft[len][ind] = (naft[len][ind] + naft[len][ind - 1] + 100L * m) % m;
                }
            }
            dp2 = dp;
            dp = new long[][][]{nbef, naft};
        }
        for(long[] row: dp[0])
            for(long i : row)
                res += i;
        for(long[] row: dp[1])
            for(long i : row)
                res += i;
            out.println(res % m);
        return false;
    }

    // edges to adjacency list by uwi
    public static int[][] packU(int n, int[] from, int[] to) {
        return packU(n, from, to, from.length);
    }

    public static int[][] packU(int n, int[] from, int[] to, int sup) {
        int[][] g = new int[n][];
        int[] p = new int[n];
        for (int i = 0; i < sup; i++) p[from[i]]++;
        for (int i = 0; i < sup; i++) p[to[i]]++;
        for (int i = 0; i < n; i++) g[i] = new int[p[i]];
        for (int i = 0; i < sup; i++) {
            g[from[i]][--p[from[i]]] = to[i];
            g[to[i]][--p[to[i]]] = from[i];
        }
        return g;
    }

    // tree diameter by uwi
    public static int[] diameter(int[][] g) {
        int n = g.length;
        int f0 = -1, f1 = -1, d01 = -1;
        int[] q = new int[n];
        boolean[] ved = new boolean[n];
        {
            int qp = 0;
            q[qp++] = 0; ved[0] = true;
            for(int i = 0;i < qp;i++){
                int cur = q[i];
                for(int e : g[cur]){
                    if(!ved[e]){
                        ved[e] = true;
                        q[qp++] = e;
                        continue;
                    }
                }
            }
            f0 = q[n-1];
        }
        {
            int[] d = new int[n];
            int qp = 0;
            Arrays.fill(ved, false);
            q[qp++] = f0; ved[f0] = true;
            for(int i = 0;i < qp;i++){
                int cur = q[i];
                for(int e : g[cur]){
                    if(!ved[e]){
                        ved[e] = true;
                        q[qp++] = e;
                        d[e] = d[cur] + 1;
                        continue;
                    }
                }
            }
            f1 = q[n-1];
            d01 = d[f1];
        }
        return new int[]{d01, f0, f1};
    }

    public static long c(int n, int k) {
        return (fac[n] * facInv[k] % MOD) * facInv[n - k] % MOD;
    }

    // SegmentTree range min/max query by uwi
    public static class SegmentTreeRMQ {
        public int M, H, N;
        public int[] st;

        public SegmentTreeRMQ(int n)
        {
            N = n;
            M = Integer.highestOneBit(Math.max(N-1, 1))<<2;
            H = M>>>1;
            st = new int[M];
            Arrays.fill(st, 0, M, Integer.MAX_VALUE);
        }

        public SegmentTreeRMQ(int[] a)
        {
            N = a.length;
            M = Integer.highestOneBit(Math.max(N-1, 1))<<2;
            H = M>>>1;
            st = new int[M];
            for(int i = 0;i < N;i++){
                st[H+i] = a[i];
            }
            Arrays.fill(st, H+N, M, Integer.MAX_VALUE);
            for(int i = H-1;i >= 1;i--)propagate(i);
        }

        public void update(int pos, int x)
        {
            st[H+pos] = x;
            for(int i = (H+pos)>>>1;i >= 1;i >>>= 1)propagate(i);
        }

        private void propagate(int i)
        {
            st[i] = Math.min(st[2*i], st[2*i+1]);
        }

        public int minx(int l, int r){
            int min = Integer.MAX_VALUE;
            if(l >= r)return min;
            while(l != 0){
                int f = l&-l;
                if(l+f > r)break;
                int v = st[(H+l)/f];
                if(v < min)min = v;
                l += f;
            }

            while(l < r){
                int f = r&-r;
                int v = st[(H+r)/f-1];
                if(v < min)min = v;
                r -= f;
            }
            return min;
        }

        public int min(int l, int r){ return l >= r ? 0 : min(l, r, 0, H, 1);}

        private int min(int l, int r, int cl, int cr, int cur)
        {
            if(l <= cl && cr <= r){
                return st[cur];
            }else{
                int mid = cl+cr>>>1;
                int ret = Integer.MAX_VALUE;
                if(cl < r && l < mid){
                    ret = Math.min(ret, min(l, r, cl, mid, 2*cur));
                }
                if(mid < r && l < cr){
                    ret = Math.min(ret, min(l, r, mid, cr, 2*cur+1));
                }
                return ret;
            }
        }
    }

    public static char[] rev(char[] a){char[] b = new char[a.length];for(int i = 0;i < a.length;i++)b[a.length-1-i] = a[i];return b;}

    public static double dist(double a, double b){
        return Math.sqrt(a * a + b * b);
    }

    public static long inv(long a){
        return quickPOW(a, MOD - 2);
    }

    public class Interval {
        int start;
        int end;
        public Interval(int start, int end) {
            this.start = start;
            this.end = end;
        }
    }

    public static ArrayList<Integer> sieveOfEratosthenes(int n) {
        boolean prime[] = new boolean[n + 1];
        Arrays.fill(prime, true);
        for (int p = 2; p * p <= n; p++) {
            if (prime[p]) {
                for (int i = p * 2; i <= n; i += p) {
                    prime[i] = false;
                }
            }
        }
        ArrayList<Integer> primeNumbers = new ArrayList<>();
        for (int i = 2; i <= n; i++) {
            if (prime[i]) {
                primeNumbers.add(i);
            }
        }
        return primeNumbers;
    }

    public static int lowerBound(int[] a, int v){ return lowerBound(a, 0, a.length, v); }
    public static int lowerBound(int[] a, int l, int r, int v)
    {
        if(l > r || l < 0 || r > a.length)throw new IllegalArgumentException();
        int low = l-1, high = r;
        while(high-low > 1){
            int h = high+low>>>1;
            if(a[h] >= v){
                high = h;
            }else{
                low = h;
            }
        }
        return high;
    }
    public static int rlowerBound(int[] a, int v){ return lowerBound(a, 0, a.length, v); }
    public static int rlowerBound(int[] a, int l, int r, int v)
    {
        if(l > r || l < 0 || r > a.length)throw new IllegalArgumentException();
        int low = l-1, high = r;
        while(high-low > 1){
            int h = high+low>>>1;
            if(a[h] <= v){
                high = h;
            }else{
                low = h;
            }
        }
        return high;
    }
    public static long C(int n, int m)
    {
        if(m == 0 || m == n) return 1l;
        if(m > n || m < 0) return 0l;
        long res = fac[n] * quickPOW((fac[m] * fac[n - m]) % MOD, MOD - 2) % MOD;

        return res;
    }
    public static long quickPOW(long n, long m)
    {
        long ans = 1l;
        while(m > 0)
        {
            if(m % 2 == 1)
                ans = (ans * n) % MOD;
            n = (n * n) % MOD;
            m >>= 1;
        }
        return ans;
    }
    public static long quickPOW(long n, long m, long mod)
    {
        long ans = 1l;
        while(m > 0)
        {
            if(m % 2 == 1)
                ans = (ans * n) % mod;
            n = (n * n) % mod;
            m >>= 1;
        }
        return ans;
    }

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

    static class Randomized {
        public static void shuffle(int[] data) {
            shuffle(data, 0, data.length - 1);
        }

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

        public static void shuffle(long[] data) {
            shuffle(data, 0, data.length - 1);
        }

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

        public static int nextInt(int l, int r) {
            return RandomWrapper.INSTANCE.nextInt(l, r);
        }
    }

    static class RandomWrapper {
        private Random random;
        public static final RandomWrapper INSTANCE = new RandomWrapper(new Random());

        public RandomWrapper() {
            this(new Random());
        }

        public RandomWrapper(Random random) {
            this.random = random;
        }

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

    }

    //-----------MyScanner class for faster input----------
    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }
        int ni() {
            return Integer.parseInt(next());
        }
        long nl() {
            return Long.parseLong(next());
        }
        double nd() {
            return Double.parseDouble(next());
        }
        String nextLine(){
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }
    //--------------------------------------------------------
}


/*
  Goal: Become better in CP!
  Key: Consistency and Discipline
  Desire: SDE @ Google USA
  Motto: Do what i Love <=> Love what i do
  If you don't use your brain 100%, it deteriorates gradually
*/

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

public class Solution {

  static StringBuffer str=new StringBuffer();
  static BufferedReader bf;
  static PrintWriter pw;
  static int n, x;
  static long mod=998244353l;
  static long dp[][];
  static long comb[][];

  static long mod_mul(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a * b) % mod) + mod) % mod;
  }

  static long mod_add(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a + b) % mod) + mod) % mod;
  }

  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 = b >> 1l;
    }
    return res;
  }

  // O(n*x*n) solution
  static long count(int i, int j){
    if(i==1) return 0;
    if(i==0) return 1;
    if(j>=x) return 0;
    if(dp[i][j]!=-1) return dp[i][j];

    int cost = Math.min(x, j+i-1);
    // Transition from dp[i][j] to dp[k][cost]
    long ans=0;
    for(int k=0;k<=i;k++){
      ans=mod_add(ans, mod_mul(comb[i][i-k], mod_mul(pow(cost-j, i-k), count(k, cost))));
    }
    return dp[i][j]=ans;
  }

  // DP + Combinatorics
  static void solve(int te) throws Exception{
    comb = new long[501][501];
    comb[0][0] = 1;
    for (int i = 1; i <= 500; i++) {
      comb[i][0] = 1;
      for (int j = 1; j <= i; j++) {
        comb[i][j] = (comb[i-1][j] + comb[i-1][j-1]) % mod;
      }
    }

    /* // Top down dp

    // dp[i][j] = # of ways to choose health = required answer
    // i -> i heros still alive => i=n is required
    // j -> already received j damage => j<=x is required

    // sum of dp[0][j] for each j in [0, x] is the answer
    dp=new long[n+1][x+1];
    for(int i=0;i<=n;i++){
      for(int j=0;j<=x;j++){
        dp[i][j]=-1;
      }
    }
    str.append(count(n, 0)).append("\n");
    */
    // bottom up dp
    dp=new long[n+1][x+1];

    for(int i=0;i<=x;i++){
      dp[1][i]=0;
      dp[0][i]=1;
    }

    long pow[][]=new long[n+1][x+1];
    for(int i=0;i<=n;i++) for(int j=0;j<=x;j++) pow[i][j]=pow(i, j);
    for(int i=2;i<=n;i++){
      for(int j=x-1;j>=0;j--){
        int cost = Math.min(x, j+i-1);
        // Transition from dp[i][j] to dp[k][cost]
        long ans=0;
        for(int k=0;k<=i;k++){
          long ins2=(((pow[cost-j][i-k]%mod) * (dp[k][cost]%mod))%mod + mod)%mod;
          long ins1=(((comb[i][i-k]%mod) * (ins2%mod))%mod + mod)%mod;
          ans=((ans%mod + ins1%mod)%mod + mod)%mod;
        }
        dp[i][j]=ans;
      }
    }
    str.append(dp[n][0]).append("\n");
  }

  public static void main(String[] args) throws java.lang.Exception {
    boolean lenv=false;
    int te=1;
    if(lenv){
      bf = new BufferedReader(
                          new FileReader("input.txt"));
      pw=new PrintWriter(new
            BufferedWriter(new FileWriter("output.txt")));
    }else{
      bf = new BufferedReader(new InputStreamReader(System.in));
      pw = new PrintWriter(new OutputStreamWriter(System.out));
    }

    // int q1 = Integer.parseInt(bf.readLine().trim());
    // for(te=1;te<=q1;te++) {
      String s[]=bf.readLine().trim().split("\\s+");
      n=Integer.parseInt(s[0]);
      x=Integer.parseInt(s[1]);
      solve(te);
    // }
    pw.print(str);
    pw.flush();
    // System.out.println(str);
  }
}


/*
  Goal: Become better in CP!
  Key: Consistency and Discipline
  Desire: SDE @ Google USA
  Motto: Do what i Love <=> Love what i do
  If you don't use your brain 100%, it deteriorates gradually
*/

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

public class Solution {

  static StringBuffer str=new StringBuffer();
  static BufferedReader bf;
  static PrintWriter pw;
  static int n, x;
  static long mod=998244353l;
  static long dp[][];
  static long comb[][];

  static long mod_mul(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a * b) % mod) + mod) % mod;
  }

  static long mod_add(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a + b) % mod) + mod) % mod;
  }

  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 = b >> 1l;
    }
    return res;
  }

  // O(n*x*n) solution
  static long count(int i, int j){
    if(i==1) return 0;
    if(i==0) return 1;
    if(j>=x) return 0;
    if(dp[i][j]!=-1) return dp[i][j];

    int cost = Math.min(x, j+i-1);
    // Transition from dp[i][j] to dp[k][cost]
    long ans=0;
    for(int k=0;k<=i;k++){
      ans=mod_add(ans, mod_mul(comb[i][i-k], mod_mul(pow(cost-j, i-k), count(k, cost))));
    }
    return dp[i][j]=ans;
  }

  // DP + Combinatorics
  static void solve(int te) throws Exception{
    int mx=Math.max(n+1, x+1);
    mx+=10;
    comb = new long[mx][mx];
    comb[0][0] = 1;
    for (int i = 1; i <= mx; i++) {
      comb[i][0] = 1;
      for (int j = 1; j <= i; j++) {
        comb[i][j] = (comb[i-1][j] + comb[i-1][j-1]) % mod;
      }
    }

    /* // Top down dp

    // dp[i][j] = # of ways to choose health = required answer
    // i -> i heros still alive => i=n is required
    // j -> already received j damage => j<=x is required

    // sum of dp[0][j] for each j in [0, x] is the answer
    dp=new long[n+1][x+1];
    for(int i=0;i<=n;i++){
      for(int j=0;j<=x;j++){
        dp[i][j]=-1;
      }
    }
    str.append(count(n, 0)).append("\n");
    */
    // bottom up dp
    dp=new long[n+1][x+1];

    for(int i=0;i<=x;i++){
      dp[1][i]=0;
      dp[0][i]=1;
    }

    long pow[][]=new long[n+1][x+1];
    for(int i=0;i<=mx;i++) for(int j=0;j<=mx;j++) pow[i][j]=pow(i, j);
    for(int i=2;i<=n;i++){
      for(int j=x-1;j>=0;j--){
        int cost = Math.min(x, j+i-1);
        // Transition from dp[i][j] to dp[k][cost]
        long ans=0;
        for(int k=0;k<=i;k++){
          long ins2=(((pow[cost-j][i-k]%mod) * (dp[k][cost]%mod))%mod + mod)%mod;
          long ins1=(((comb[i][i-k]%mod) * (ins2%mod))%mod + mod)%mod;
          ans=((ans%mod + ins1%mod)%mod + mod)%mod;
        }
        dp[i][j]=ans;
      }
    }
    str.append(dp[n][0]).append("\n");
  }

  public static void main(String[] args) throws java.lang.Exception {
    boolean lenv=false;
    int te=1;
    if(lenv){
      bf = new BufferedReader(
                          new FileReader("input.txt"));
      pw=new PrintWriter(new
            BufferedWriter(new FileWriter("output.txt")));
    }else{
      bf = new BufferedReader(new InputStreamReader(System.in));
      pw = new PrintWriter(new OutputStreamWriter(System.out));
    }

    // int q1 = Integer.parseInt(bf.readLine().trim());
    // for(te=1;te<=q1;te++) {
      String s[]=bf.readLine().trim().split("\\s+");
      n=Integer.parseInt(s[0]);
      x=Integer.parseInt(s[1]);
      solve(te);
    // }
    pw.print(str);
    pw.flush();
    // System.out.println(str);
  }
}


/*
  Goal: Become better in CP!
  Key: Consistency and Discipline
  Desire: SDE @ Google USA
  Motto: Do what i Love <=> Love what i do
  If you don't use your brain 100%, it deteriorates gradually
*/

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

public class Solution {

  static StringBuffer str=new StringBuffer();
  static BufferedReader bf;
  static PrintWriter pw;
  static int n, x;
  static long mod=998244353l;
  static long dp[][];
  static long comb[][];

  static long mod_mul(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a * b) % mod) + mod) % mod;
  }

  static long mod_add(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a + b) % mod) + mod) % mod;
  }

  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 = b >> 1l;
    }
    return res;
  }

  // O(n*x*n) solution
  static long count(int i, int j){
    if(i==1) return 0;
    if(i==0) return 1;
    if(j>=x) return 0;
    if(dp[i][j]!=-1) return dp[i][j];

    int cost = Math.min(x, j+i-1);
    // Transition from dp[i][j] to dp[k][cost]
    long ans=0;
    for(int k=0;k<=i;k++){
      ans=mod_add(ans, mod_mul(comb[i][i-k], mod_mul(pow(cost-j, i-k), count(k, cost))));
    }
    return dp[i][j]=ans;
  }

  // DP + Combinatorics
  static void solve(int te) throws Exception{
    int mx=Math.max(n+1, x+1);
    comb = new long[mx][mx];
    comb[0][0] = 1;
    for (int i = 1; i <= mx; i++) {
      comb[i][0] = 1;
      for (int j = 1; j <= i; j++) {
        comb[i][j] = (comb[i-1][j] + comb[i-1][j-1]) % mod;
      }
    }

    /* // Top down dp

    // dp[i][j] = # of ways to choose health = required answer
    // i -> i heros still alive => i=n is required
    // j -> already received j damage => j<=x is required

    // sum of dp[0][j] for each j in [0, x] is the answer
    dp=new long[n+1][x+1];
    for(int i=0;i<=n;i++){
      for(int j=0;j<=x;j++){
        dp[i][j]=-1;
      }
    }
    str.append(count(n, 0)).append("\n");
    */
    // bottom up dp
    dp=new long[n+1][x+1];

    for(int i=0;i<=x;i++){
      dp[1][i]=0;
      dp[0][i]=1;
    }

    long pow[][]=new long[n+1][x+1];
    for(int i=0;i<=mx;i++) for(int j=0;j<=mx;j++) pow[i][j]=pow(i, j);
    for(int i=2;i<=n;i++){
      for(int j=x-1;j>=0;j--){
        int cost = Math.min(x, j+i-1);
        // Transition from dp[i][j] to dp[k][cost]
        long ans=0;
        for(int k=0;k<=i;k++){
          long ins2=(((pow[cost-j][i-k]%mod) * (dp[k][cost]%mod))%mod + mod)%mod;
          long ins1=(((comb[i][i-k]%mod) * (ins2%mod))%mod + mod)%mod;
          ans=((ans%mod + ins1%mod)%mod + mod)%mod;
        }
        dp[i][j]=ans;
      }
    }
    str.append(dp[n][0]).append("\n");
  }

  public static void main(String[] args) throws java.lang.Exception {
    boolean lenv=false;
    int te=1;
    if(lenv){
      bf = new BufferedReader(
                          new FileReader("input.txt"));
      pw=new PrintWriter(new
            BufferedWriter(new FileWriter("output.txt")));
    }else{
      bf = new BufferedReader(new InputStreamReader(System.in));
      pw = new PrintWriter(new OutputStreamWriter(System.out));
    }

    // int q1 = Integer.parseInt(bf.readLine().trim());
    // for(te=1;te<=q1;te++) {
      String s[]=bf.readLine().trim().split("\\s+");
      n=Integer.parseInt(s[0]);
      x=Integer.parseInt(s[1]);
      solve(te);
    // }
    pw.print(str);
    pw.flush();
    // System.out.println(str);
  }
}


/*
  Goal: Become better in CP!
  Key: Consistency and Discipline
  Desire: SDE @ Google USA
  Motto: Do what i Love <=> Love what i do
  If you don't use your brain 100%, it deteriorates gradually
*/

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

public class Solution {

  static StringBuffer str=new StringBuffer();
  static BufferedReader bf;
  static PrintWriter pw;
  static int n, x;
  static long mod=998244353l;
  static long dp[][];
  static long comb[][];

  static long mod_mul(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a * b) % mod) + mod) % mod;
  }

  static long mod_add(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a + b) % mod) + mod) % mod;
  }

  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 = b >> 1l;
    }
    return res;
  }

  // O(n*x*n) solution
  static long count(int i, int j){
    if(i==1) return 0;
    if(i==0) return 1;
    if(j>=x) return 0;
    if(dp[i][j]!=-1) return dp[i][j];

    int cost = Math.min(x, j+i-1);
    // Transition from dp[i][j] to dp[k][cost]
    long ans=0;
    for(int k=0;k<=i;k++){
      ans=mod_add(ans, mod_mul(comb[i][i-k], mod_mul(pow(cost-j, i-k), count(k, cost))));
    }
    return dp[i][j]=ans;
  }

  // DP + Combinatorics
  static void solve(int te) throws Exception{
    int mx=501;
    comb = new long[mx][mx];
    comb[0][0] = 1;
    for (int i = 1; i <= mx; i++) {
      comb[i][0] = 1;
      for (int j = 1; j <= i; j++) {
        comb[i][j] = (comb[i-1][j] + comb[i-1][j-1]) % mod;
      }
    }

    /* // Top down dp

    // dp[i][j] = # of ways to choose health = required answer
    // i -> i heros still alive => i=n is required
    // j -> already received j damage => j<=x is required

    // sum of dp[0][j] for each j in [0, x] is the answer
    dp=new long[n+1][x+1];
    for(int i=0;i<=n;i++){
      for(int j=0;j<=x;j++){
        dp[i][j]=-1;
      }
    }
    str.append(count(n, 0)).append("\n");
    */
    // bottom up dp
    dp=new long[n+1][x+1];

    for(int i=0;i<=x;i++){
      dp[1][i]=0;
      dp[0][i]=1;
    }

    long pow[][]=new long[n+1][x+1];
    for(int i=0;i<=mx;i++) for(int j=0;j<=mx;j++) pow[i][j]=pow(i, j);
    for(int i=2;i<=n;i++){
      for(int j=x-1;j>=0;j--){
        int cost = Math.min(x, j+i-1);
        // Transition from dp[i][j] to dp[k][cost]
        long ans=0;
        for(int k=0;k<=i;k++){
          long ins2=(((pow[cost-j][i-k]%mod) * (dp[k][cost]%mod))%mod + mod)%mod;
          long ins1=(((comb[i][i-k]%mod) * (ins2%mod))%mod + mod)%mod;
          ans=((ans%mod + ins1%mod)%mod + mod)%mod;
        }
        dp[i][j]=ans;
      }
    }
    str.append(dp[n][0]).append("\n");
  }

  public static void main(String[] args) throws java.lang.Exception {
    boolean lenv=false;
    int te=1;
    if(lenv){
      bf = new BufferedReader(
                          new FileReader("input.txt"));
      pw=new PrintWriter(new
            BufferedWriter(new FileWriter("output.txt")));
    }else{
      bf = new BufferedReader(new InputStreamReader(System.in));
      pw = new PrintWriter(new OutputStreamWriter(System.out));
    }

    // int q1 = Integer.parseInt(bf.readLine().trim());
    // for(te=1;te<=q1;te++) {
      String s[]=bf.readLine().trim().split("\\s+");
      n=Integer.parseInt(s[0]);
      x=Integer.parseInt(s[1]);
      solve(te);
    // }
    pw.print(str);
    pw.flush();
    // System.out.println(str);
  }
}


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

public class Main {

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        // input
        int n = sc.nextInt();
        int m = sc.nextInt();
        long[][] matrix = new long[n+1][m+1];
        for(int x = 0; x <= n; ++x) {
            matrix[x][m] = 0;
        }
        for(int y = 0; y <= m; ++y) {
            matrix[n][y] = 0;
        }
        matrix[n-1][m-1] = 1;
        int k = sc.nextInt();
        for(int i = 0; i < k; ++i) {
            int x1 = sc.nextInt();
            int y1 = sc.nextInt();
            int x2 = sc.nextInt();
            int y2 = sc.nextInt();
            for(int x = x1; x <= x2; ++x) {
                for(int y = y1; y <= y2; ++y) {
                    matrix[x-1][y-1] = -1;
                }
            }
        }

        // computation: dynamic programming in matrix
        // value of n, m is 1
        // if getTopRight is blocked, value is sum of getTop and getRight
        // else value is maximum of getTop and getRight
        for(int y = m - 1; y >= 0; --y) {
            for(int x = n - 1; x >= 0; --x) {
                if(matrix[x][y] == -1) {
                    matrix[x][y] = 0;
                } else {
                    if(x == n - 1 && y == m - 1) {
                        matrix[x][y] = 1;
                    } else if(matrix[x+1][y] == 0 || matrix[x][y+1] == 0) {
                        matrix[x][y] = Math.max(matrix[x][y + 1], matrix[x + 1][y]);
                    } else {
                        matrix[x][y] = (matrix[x+1][y] - matrix[x+1][y+1]) + matrix[x][y+1];
                    }
                }
                if(matrix[x][y] == 5050357768079792430) {
                    for(int a = y+3; a >= y; a--) {
                        for(int b = x; b < x+3; b++) {
                            System.out.print(matrix[b][a] + " ");
                        }
                        System.out.println();
                    }
                }
            }
        }
        /*for(int y = m - 1; y >= 0; y--) {
            for(int x = 0; x < n; x++) {
                System.out.print(matrix[x][y] + " ");
            }
            System.out.println();
        }*/

        System.out.println(matrix[0][0]);

    }
}


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

public class Slalom {

	public final static int modulo = 1000000007;

	public class SegmentTree {
		SegmentTree(int size) {
			int treeSize = biggerPowerOfTwo(size) * 2 - 1;
			updated = new boolean[treeSize];
			tree = new int[treeSize];
			forwardAdd = new boolean[treeSize];
			this.size = size;
			build(0, 0, size - 1);
		}

		public void reset(int l, int r) {
			resetRec(0, 0, size - 1, l, r);
		}

		public int get(int pos) {
			return getRec(0, 0, size - 1, pos);
		}

		public void add(int l, int r, int value) {
			if(value > 0)
				addRec(0, 0, size - 1, l, r, value);
		}

		public void print(int[] array) {
			printOrigRec(0, 0, size - 1, array);
		}

		@Override
		public String toString() {
			String result = new String();
			int treeSize = biggerPowerOfTwo(size) * 2 - 1;
			for(int i = 0; i < treeSize; ++i) {
				result += tree[i] + " ";
			}
			return result;
		}

		private void printOrigRec(int root, int start, int end, int[] array) {
			if(start == end) {
				array[start] = tree[root];
			} else {
				int mid = mid(start, end);
				forward(root, start, end);
				printOrigRec(left(root), start, mid, array);
				printOrigRec(right(root), mid + 1, end, array);
			}
		}

		private void build(int root, int start, int end) {
			tree[root] = 0;
			forwardAdd[root] = false;
			updated[root] = false;
			if(start < end) {
				int mid = mid(start, end);
				build(left(root), start, mid);
				build(right(root), mid + 1, end);
			}
		}

		private void resetRec(int root, int start, int end, int l, int r) {
			if(l > end  || r < start) return; // no intersection
			else if(l <= start && end <= r) { // fully contained
				tree[root] = 0;
				updated[root] = true;
				forwardAdd[root] = false;
			}
			else {
				forward(root, start, end);
				int mid = mid(start, end);
				resetRec(left(root), start, mid, l, r);
				resetRec(right(root), mid + 1, end, l, r);
			}
		}

		private int getRec(int root, int start, int end, int pos) {
			if(start == end) {
				return tree[root];
			}
			int mid = mid(start, end);
			forward(root, start, end);
			if(pos <= mid) {
				return getRec(left(root), start, mid, pos);
			}
			else {
				return getRec(right(root), mid + 1, end, pos);
			}
		}

		private void addRec(int root, int start, int end, int l, int r, int v) {
			if(l > end  || r < start) return; // no intersection
			else if(l <= start && end <= r) { // fully contained
				addToNode(root, v);
			}
			else {
				forward(root, start, end);
				int mid = mid(start, end);
				addRec(left(root), start, mid, l, r, v);
				addRec(right(root), mid + 1, end, l, r, v);
			}
		}

		private void addToNode(int root, int v) {
			if(v > 0) {
				tree[root] = (tree[root] + v) % modulo;
				if(!updated[root]) {
					updated[root] = true;
					forwardAdd[root] = true;
				} // else: if child was updated with ... add -> add more. ... set -> set more
			}
		}

		private void forward(int root, int start, int end) {
			if(start == end) { // leaf
				forwardAdd[root] = false;
			} else {
				if(updated[root]) {
					if(forwardAdd[root]) {	// add value of root to children
						addToNode(left(root), tree[root]);
						addToNode(right(root), tree[root]);
					} else {			// set value of root to children
						tree[left(root)] = tree[root];
						tree[right(root)] = tree[root];
						tree[root] = 0;
						// children have to set their children as well.
						forwardAdd[left(root)] = false;
						forwardAdd[right(root)] = false;
						updated[left(root)] = true;
						updated[right(root)] = true;
					}

				}
			}
			tree[root] = 0;
			updated[root] = false;
			forwardAdd[root] = false;
		}

		private int left(int root) {
			return 2 * root + 1;
		}

		private int right(int root) {
			return 2 * root + 2;
		}

		private int mid(int l, int r) {
			return (l+r) / 2;
		}

		private int biggerPowerOfTwo(int x) {
			return Integer.highestOneBit(x) << 1;
		}

		private int[] tree;
		private boolean[] updated;
		// forwardAdd == true means that the current value has to be added to all children
		// forwardAdd == false means that the current value has to be set to all children
		private boolean[] forwardAdd;

		private int size;
	}

	public class Block implements Comparable<Block> {
		int id;
		int x;
		int y1;
		int y2;
		boolean rightBorder;

		Block(int id, int x, int y1, int y2, boolean ends) {
			this.id = id;
			this.x = x;
			this.y1 = y1;
			this.y2 = y2;
			this.rightBorder = ends;
		}

		// the order defined here is crucial to the correctness of the algorithm.
		// at a position x: event "end" triggers update until next active block. hence more downwards "ends" have to come first to deactivate a block
		// but all "starts" have to come first as well to activate a block.
		@Override
		public int compareTo(Block o) {
			// first compare x (higher x is smaller), then the one with a right border comes first. if both same direction, then smaller y1 is smaller
			if(this.x == o.x)
				// starting first
				if(this.rightBorder == o.rightBorder) {
					return this.y1 - o.y1; // lower first
				} else {
					if(this.rightBorder) return -1;
					else return +1;
				}
			else
				return o.x - this.x;
		}
	}

	public class ActiveBlock implements Comparable<ActiveBlock> {
		int id;
		int topY;

		ActiveBlock(int id, int y) {
			this.id = id;
			this.topY = y;
		}

		@Override
		public int compareTo(ActiveBlock o) {
			if(this.topY == o.topY) {
				return this.id - o.id;
			}
			return this.topY - o.topY;
		}
	}

	public void solve() throws FileNotFoundException {
		Scanner sc = new Scanner(System.in);

//		Scanner sc = new Scanner(new File("Tests/Slalom/27"));
		// input
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();

		Block[] blocks = new Block[2*k+1];
		for(int i = 0; i < k; ++i) {
			int x1 = sc.nextInt();
			int y1 = sc.nextInt();
			int x2 = sc.nextInt();
			int y2 = sc.nextInt();
			blocks[i] = new Block(i, x2, y1, y2, true);	// as we proceed from right to left, a block "starts" at its right border.
			blocks[k + i] = new Block(i, x1 - 1 , y1, y2, false); // "ending" blocks are processed _after_ they have ended, so store them at x1 - 1
		}
		blocks[2*k] = new Block(k, n, m-1, m-1, false); //dummy ending block, right of and below (n, m), so stored at (n, m-1)
		Arrays.sort(blocks);
		sc.close();

		//DEBUG:
//		int[][] matrix = new int[n][m + 2];

		// computation: dynamic programming in matrix
		// value of n, m is 1
		// if getTopRight is blocked, value is sum of getTop and getRight
		// else value is maximum of getTop and getRight
		// space improvement: only store current column of matrix. Use set of blocks to keep track of currently active blocks.
		// time improvement: use segment tree with operations reset(l, r), get(pos) and add(l, r) for this column
		SegmentTree col = new SegmentTree(m + 2);
		col.add(m, m, 1);
		NavigableSet<ActiveBlock> activeBlocks = new TreeSet<ActiveBlock>();
		int i = 0;
		for(int x = n; x >= 1; --x) {
			while((i < 2*k + 1) && blocks[i].x == x) {
				Block curBlock = blocks[i];
				if(curBlock.rightBorder) { // starting blocks
					activeBlocks.add(new ActiveBlock(curBlock.id, curBlock.y2));
					col.reset(curBlock.y1, curBlock.y2);
				} else { // ending blocks
					activeBlocks.remove(new ActiveBlock(curBlock.id, curBlock.y2));
					// all squares left of that block, starting from the y2 of that block to the active next block (search in activeBlocks)
					ActiveBlock lower = activeBlocks.floor(new ActiveBlock(k + 1, curBlock.y2));
					if(lower == null) lower = new ActiveBlock(k + 1, 0);
					if(lower.topY <= curBlock.y2) {
						int value = col.get(curBlock.y2 + 1);
						col.add(lower.topY + 1, curBlock.y2, value);
					}
				}
				++i;
			}
			// DEBUG:
//			col.print(matrix[x-1]);

		}

		// DEBUG:
//		for(int Y = m; Y >= 1; Y--) {
//            for(int X = 0; X < n; X++) {
//                System.out.print((matrix[X][Y] < 10 ? " " : "") + matrix[X][Y] + " ");
//            }
//            System.out.println();
//        }

		System.out.println(col.get(1));
	}

	public static void main(String[] args) throws IOException {
		new Slalom().solve();
	}

}


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

public class Slalom {

	public final static long modulo = 1000000007;

	public class Block implements Comparable<Block> {
		int x;
		int y1;
		int y2;
		boolean rightBorder;

		Block(int x, int y1, int y2, boolean ends) {
			this.x = x;
			this.y1 = y1;
			this.y2 = y2;
			this.rightBorder = ends;
		}

		@Override
		public int compareTo(Block o) {
			// first compare x (higher x is smaller), then the one with a right border comes first. if both same direction, then smaller y1 is smaller
			if(this.x == o.x)
				// starting first
				if(this.rightBorder == o.rightBorder) {
					return o.y1 - this.y1;
				} else {
					if(o.rightBorder) return +1;
					else return -1;
				}
			else
				return o.x - this.x;
		}
	}

	public void solve() throws FileNotFoundException {
		//Scanner sc = new Scanner(System.in);

		File file = new File("Tests/Slalom/04");
		Scanner sc = new Scanner(file);
		// input
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();

		Block[] blocks = new Block[2*k+1];
		for(int i = 0; i < k; ++i) {
			int x1 = sc.nextInt();
			int y1 = sc.nextInt();
			int x2 = sc.nextInt();
			int y2 = sc.nextInt();
			blocks[i] = new Block(x2, y1, y2, true);	// as we proceed from right to left, a block "starts" at its right border.
			blocks[k + i] = new Block(x1 - 1 , y1, y2, false); // "ending" blocks are processed _after_ they have ended, so store them at x1 - 1
		}
		blocks[2*k] = new Block(n, m-1, m-1, false); //dummy ending block, right of and below (n, m), so stored at (n, m-1)
		Arrays.sort(blocks);
		sc.close();

		//DEBUG:
		//int[][] matrix = new int[n][m];

		// computation: dynamic programming in matrix
		// value of n, m is 1
		// if getTopRight is blocked, value is sum of getTop and getRight
		// else value is maximum of getTop and getRight
		// space improvement: only store current column of matrix. Use set of blocks to keep track of currently active blocks.
		int[] col = new int[m + 2];
		col[m] = 1;
		NavigableSet<Integer> activeBlocks = new TreeSet<Integer>();
		int i = 0;
		for(int x = n; x >= 1; --x) {
			while((i < 2*k + 1) && blocks[i].x == x) {
				Block curBlock = blocks[i];
				if(curBlock.rightBorder) { // starting blocks
					activeBlocks.add(curBlock.y2);
					for(int y = curBlock.y2; y >= curBlock.y1; --y) {
						col[y] = 0;
					}
				} else { // ending blocks
					activeBlocks.remove(curBlock.y2);
					// all squares left of that block, starting from the y2 of that block to the active next block (search in activeBlocks)
					Integer lower = activeBlocks.floor(curBlock.y2);
					if(lower == null) lower = 0;
					for(int y = curBlock.y2; y > lower; --y) {
						col[y] += col[curBlock.y2 + 1] % modulo;
					}
				}
				++i;
			}
			// DEBUG:
//			for(int j = 0; j < m; ++j)
//				matrix[x-1][j] = col[j + 1];
		}

		// DEBUG:
//		for(int Y = m - 1; Y >= 0; Y--) {
//            for(int X = 0; X < n; X++) {
//                System.out.print((matrix[X][Y] < 10 ? " " : "") + matrix[X][Y] + " ");
//            }
//            System.out.println();
//        }

		System.out.println(col[1]);
	}

	public static void main(String[] args) throws IOException {
		new Slalom().solve();
	}

}


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

public class Main {

    public final static long modulo = 1000000007;

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        // input
        int n = sc.nextInt();
        int m = sc.nextInt();
        long[][] matrix = new long[n+1][m+1];
        /*for(int x = 0; x <= n; ++x) {
            matrix[x][m] = 0;
        }
        for(int y = 0; y <= m; ++y) {
            matrix[n][y] = 0;
        }*/
        matrix[n-1][m-1] = 1;
        int k = sc.nextInt();
        for(int i = 0; i < k; ++i) {
            int x1 = sc.nextInt();
            int y1 = sc.nextInt();
            int x2 = sc.nextInt();
            int y2 = sc.nextInt();
            for(int x = x1; x <= x2; ++x) {
                for(int y = y1; y <= y2; ++y) {
                    matrix[x-1][y-1] = -1;
                }
            }
        }

        // computation: dynamic programming in matrix
        // value of n, m is 1
        // if getTopRight is blocked, value is sum of getTop and getRight
        // else value is maximum of getTop and getRight
        for(int y = m - 1; y >= 0; --y) {
            for(int x = n - 1; x >= 0; --x) {
                if(matrix[x][y] == -1) {
                    matrix[x][y] = 0;
                } else {
                    if(x == n - 1 && y == m - 1) {
                        matrix[x][y] = 1;
                    } else if(matrix[x+1][y] == 0 || matrix[x][y+1] == 0) {
                        matrix[x][y] = (Math.max(matrix[x][y + 1], matrix[x + 1][y]) + modulo) % modulo;
                    } else {
                        matrix[x][y] = (matrix[x+1][y] + matrix[x][y+1] - matrix[x+1][y+1] + modulo) % modulo;
                    }
                }
            }
        }
        /*for(int y = m - 1; y >= 0; y--) {
            for(int x = 0; x < n; x++) {
                System.out.print((matrix[x][y] < 10 ? " " : "") + matrix[x][y] + " ");
            }
            System.out.println();
        }*/

        System.out.println(matrix[0][0]);

    }
}


import java.util.Arrays;
import java.util.Scanner;

/**
 * Created by zephyr on 11/5/14.
 */
    public class Factory {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int a = scanner.nextInt();
        int m = scanner.nextInt();
        int[] values = new int[m];
        a = a % m;
        Arrays.fill(values, 0);
        if (a == 0) {
            System.out.println("YES");
            return;
        }
        values[a] = 1;
        for (int i = 1; i < 100000000; i++) {
            a = (a * 2) % m;
            if (a == 0) {
                System.out.println("YES");
                return;
            }
            if (values[a] == 1) {
                System.out.println("NO");
                return;
            } else {
                values[a] = 1;
            }

        }
    }


import java.util.*;
public class susbus{
   public static void main(String[] args){
      Scanner sc= new Scanner(System.in);
      int a = sc.nextInt();
      int m = sc.nextInt();
      int k = m/a;
      if((m%a==0 && isPowerofTwo(k)) || isPowerOfTwo(m)) System.out.println("Yes");
      else System.out.println("No");
   }
   public static boolean isPowerOfTwo(int n){
      if(n==0) return false;

         while(n>1){
            if(n%2!= 0) return false;

            n=n/2;
         }
         return true;
      }
   }


import java.util.*;
public class susbus{
   public static void main(String[] args){
      Scanner sc= new Scanner(System.in);
      int a = sc.nextInt();
      int m = sc.nextInt();

      if((m%a==0 && isPowerofTwo(m/a)) || isPowerOfTwo(m)) System.out.println("Yes");
      else System.out.println("No");
   }
   public static boolean isPowerOfTwo(int n){
         while(n>1){
            if(n%2!= 0) return false;

            n=n/2;
         }
         return true;
      }
   }


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class D
{
    public static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    public static StringTokenizer inp;
    public static void main(String[] args)  throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int ln[] = new int[1026];
        ln[0] = 0 ; ln[1023] = 2000000000;
        int ind = 1;
        for(int i = 2 ; i < 1024 ; i++)
        {
            char s[] = Integer.toBinaryString(i).toCharArray();
            for(int j = 1 ; j < s.length ; j++) s[j] = (s[j]=='0'?'4':'7');
            ln[ind++] = Integer.parseInt(String.valueOf(s).substring(1));
        }
        inp = new StringTokenizer(br.readLine());
        int pl = nextInt(),pr = nextInt() , vl=nextInt() , vr = nextInt() , k = nextInt();
        long ans = 0;
        int l = 1, r = k;
        for(; r <= 1022 ; r++,l++)
        {
            if(vl>ln[l])continue;
            if(ln[r] > pr || ln[l-1] > vr)break;
            ans+=(long)Math.max(0, (Math.min(ln[l], vr)- Math.max(vl, ln[l-1]+1) + 1))*Math.max(0, (Math.min(pr, ln[r+1]-1)- Math.max(ln[r], pl) + 1));
        }
        l=1;r=k;
        for(; r <= 1022 ; r++,l++)
        {
            if(pl>ln[l])continue;
            if(ln[r] > vr || ln[l-1] > pr)break;
            ans+=(long)Math.max(0, (Math.min(ln[l], pr)- Math.max(pl, ln[l-1]+1) + 1))*Math.max(0, (Math.min(vr, ln[r+1]-1)- Math.max(ln[r], vl) + 1));
        }
        if(k==1)
        {
            for(int i = 1; i <= 1022 ; i++)
                if(pl<=ln[i] && ln[i]<=pr && vl<=ln[i]&&ln[i]<=vr)ans--;
        }
        double res = (double)(ans)/((long)(pr-pl+1)*(vr-vl+1));
        System.out.printf("%.12f\n",Math.min(res, 1.0));
    }

    public static int nextInt(){return Integer.parseInt(inp.nextToken());}
    public static long nextLong(){return Long.parseLong(inp.nextToken());}
    public static double nextDouble(){return Double.parseDouble(inp.nextToken());}

}


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

/**
 * Author -
 * User: kansal
 * Date: 8/29/11
 * Time: 10:41 PM
 */
public class LuckyProbable {
    public static void main(String[] args) {
        reader = new BufferedReader(new InputStreamReader(System.in));

        generateLuckyNums();

        int p1 = nextInt(), p2 = nextInt(), v1 = nextInt(), v2 = nextInt(), k = nextInt();
        final int MAX = 1000000001;

        double res = 0.0;
        int n = luckyNums.size();
        for(int i = 0; i < n; ++i) {
            int j = i + k - 1;
            if (j >= n) {
                break;
            }

            int a1 = (i == 0 ? 0 : luckyNums.get(i - 1)) + 1;
            int a2 = luckyNums.get(i);
            int b1 = luckyNums.get(j);
            int b2 = (j == n-1 ? MAX : luckyNums.get(j + 1)) - 1;

            res += calc(a1, a2, b1, b2, p1, p2, v1, v2);
            res += calc(b1, b2, a1, a2, p1, p2, v1, v2);
        }

        double tot = 1.0 * (p2 - p1 + 1) * (v2 - v1 + 1);

        System.out.println(res/tot);
    }

    private static double calc(int a1, int a2, int b1, int b2, int p1, int p2, int v1, int v2) {
        double x = calc(a1, a2, p1, p2);
        double y = calc(b1, b2, v1, v2);
        return x * y;
    }

    private static double calc(int a1, int a2, int p1, int p2) {
        int x = Math.max(a1, p1);
        int y = Math.min(a2, p2);
        return Math.max(y - x + 1, 0);
    }

    private static ArrayList<Integer> luckyNums;

    private static void generateLuckyNums() {
        luckyNums = new ArrayList<Integer>();
        int[] digit = new int[]{4,7};

        for(int bitLen = 1; bitLen < 10; ++bitLen) {
            for(int b = 0; b < (1 << bitLen); ++b) {
                int n = 0;
                for(int i = 0; i < bitLen; ++i) {
                    n = n * 10 + digit[(b >> i) & 1];
                }
                luckyNums.add(n);
            }
        }

        Collections.sort(luckyNums);
    }

    public static BufferedReader reader;

    public static StringTokenizer tokenizer = null;

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

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

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

    static public String next() {
        return nextToken();
    }

    static public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}


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

/**
 * Author -
 * User: kansal
 * Date: 8/29/11
 * Time: 10:41 PM
 */
public class LuckyProbable {
    public static void main(String[] args) {
        reader = new BufferedReader(new InputStreamReader(System.in));

        generateLuckyNums();

        int p1 = nextInt(), p2 = nextInt(), v1 = nextInt(), v2 = nextInt(), k = nextInt();
        final int MAX = 1000000000;

        double res = 0.0;
        int n = luckyNums.size();
        for(int i = 0; i < n; ++i) {
            int j = i + k - 1;
            if (j >= n) {
                break;
            }

            int a1 = (i == 0 ? 0 : luckyNums.get(i - 1)) + 1;
            int a2 = luckyNums.get(i);
            int b1 = luckyNums.get(j);
            int b2 = (j == n-1 ? MAX : luckyNums.get(j + 1)) - 1;

            res += calc(a1, a2, b1, b2, p1, p2, v1, v2);
            res += calc(b1, b2, a1, a2, p1, p2, v1, v2);
        }

        double tot = 1.0 * (p2 - p1 + 1) * (v2 - v1 + 1);

        System.out.println(res/tot);
    }

    private static double calc(int a1, int a2, int b1, int b2, int p1, int p2, int v1, int v2) {
        double x = calc(a1, a2, p1, p2);
        double y = calc(b1, b2, v1, v2);
        return x * y;
    }

    private static double calc(int a1, int a2, int p1, int p2) {
        int x = Math.max(a1, p1);
        int y = Math.min(a2, p2);
        return Math.max(y - x + 1, 0);
    }

    private static ArrayList<Integer> luckyNums;

    private static void generateLuckyNums() {
        luckyNums = new ArrayList<Integer>();
        int[] digit = new int[]{4,7};

        for(int bitLen = 1; bitLen < 10; ++bitLen) {
            for(int b = 0; b < (1 << bitLen); ++b) {
                int n = 0;
                for(int i = 0; i < bitLen; ++i) {
                    n = n * 10 + digit[(b >> i) & 1];
                }
                luckyNums.add(n);
            }
        }

        Collections.sort(luckyNums);
    }

    public static BufferedReader reader;

    public static StringTokenizer tokenizer = null;

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

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

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

    static public String next() {
        return nextToken();
    }

    static public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}


import java.util.Scanner;

public class LuckyProbability
{
    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        int pl = sc.nextInt();
        int pr = sc.nextInt();
        int vl = sc.nextInt();
        int vr = sc.nextInt();
        int k = sc.nextInt();

        int ln = 1 << 9;
        int[] lucky = new int[ln];
        int y = 0;
        for (int b = 1; b <= 8; ++b)
        {
            for (int i = 0; i < (1 << b); ++i)
            {
                String str = Integer.toBinaryString(i);
                for (int j = str.length(); j < b; ++j)
                {
                    str = "0" + str;
                }
                str = str.replace('0', '4');
                str = str.replace('1', '7');
                lucky[y++] = Integer.parseInt(str);
            }
        }

        int n = 0;
        for (int p = pl; p <= pr; ++p)
        {
            for (int v = vl; v <= vr; ++v)
            {
                int mi = Math.min(v, p);
                int mx = Math.max(v, p);

                int ux = y - 1;
                int ui = 0;
                for (int l = 0; l < y; ++l)
                {
                    if (mx < lucky[l])
                    {
                        ux = l - 1;
                        break;
                    }
                }
                for (int l = y - 1; l >= 0; --l)
                {
                    if (mi > lucky[l])
                    {
                        ui = l + 1;
                        break;
                    }
                }
                if (k == ux - ui + 1)
                {
                    n++;
                }
            }
        }
        System.out.println((n*1.0)/((pr-pl+1)*(vr-vl+1)));
    }

}


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

import static java.lang.Math.*;

public class Main implements Runnable {

    final boolean file = false;

    int dx[] = new int[] {-1,-1,1,1};
    int dy[] = new int[] {-1,1,-1,1};

    void solve() throws Exception {
        int n = sc.nextInt();
        int m = sc.nextInt();
        int need = sc.nextInt();
        int color[][] = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if ((i + j) % 2 != 0) continue;
                color[i][j] = 0;
            }
        }
        int recolor[] = new int[n * m];
        int w;
        for (int step = 1;; step++) {
            w = 0;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if ((i + j) % 2 != 0 || color[i][j] != step - 1) continue;
                    boolean ok = true;
                    for (int k = 0; k < 4; k++) {
                        int x = i + dx[k];
                        int y = j + dy[k];
                        if (x < 0 || x >= n || y < 0 || y >= m || color[x][y] != step - 1) {
                            ok = false;
                            break;
                        }
                    }
                    if (ok) {
                        recolor[w++] = i * m + j;
                    }
                }
            }
            if (w == 0) break;

            for (int i = 0; i < w; i++) {
                int id = recolor[i];
                int x = id / m;
                int y = id % m;
                color[x][y] = step;
            }
        }
        int res = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if ((i + j) % 2 != 0) continue;
                if (color[i][j] == need - 1) res++;
            }
        }
        out.println(res);
    }

    BufferedReader in;
    PrintWriter out;
    FastScanner sc;

    static Throwable uncaught;

    public void run() {
        try {
            if (file) {
                in = new BufferedReader(new FileReader("strings.in"));
                out = new PrintWriter(new FileWriter("strings.out"));
            } else {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            }
            sc = new FastScanner(in);
            solve();
        } catch (Throwable t) {
            Main.uncaught = t;
        } finally {
            out.close();
        }
    }

    public static void main(String[] args) throws Throwable {
        Thread t = new Thread(null, new Main(), "", 128 * 1024 * 1024);
        t.start();
        t.join();
        if (uncaught != null) {
            throw uncaught;
        }
    }

}

class FastScanner {

    BufferedReader reader;
    StringTokenizer strTok;

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

    public String nextToken() throws IOException {
        while (strTok == null || !strTok.hasMoreTokens()) {
            strTok = new StringTokenizer(reader.readLine());
        }
        return strTok.nextToken();
    }

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

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

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

}


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

import static java.lang.Math.*;

public class Main implements Runnable {

    final boolean file = false;

    int dx[] = new int[] {-1,-1,1,1};
    int dy[] = new int[] {-1,1,-1,1};

    void solve() throws Exception {
        int n = sc.nextInt();
        int m = sc.nextInt();
        int need = sc.nextInt();
        int color[][] = new int[n][m];
        int cnt[][] = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if ((i + j) % 2 != 0) continue;
                cnt[i][j]++;
                color[i][j] = 0;
            }
        }
        int recolor[] = new int[n * m];
        int w;
        for (int step = 1;; step++) {
            w = 0;
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if ((i + j) % 2 != 0 || color[i][j] != step - 1) continue;
                    boolean ok = true;
                    for (int k = 0; k < 4; k++) {
                        int x = i + dx[k];
                        int y = j + dy[k];
                        if (x < 0 || x >= n || y < 0 || y >= m || color[x][y] != step - 1) {
                            ok = false;
                            break;
                        }
                    }
                    if (ok) {
                        recolor[w++] = i * m + j;
                    }
                }
            }
            if (w == 0) break;

            for (int i = 0; i < w; i++) {
                int id = recolor[i];
                int x = id / m;
                int y = id % m;
                color[x][y] = step;
                cnt[x][y]++;
            }
        }
        int res = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if ((i + j) % 2 != 0) continue;
                if (cnt[i][j] == need) res++;
            }
        }
        out.println(res);
    }

    BufferedReader in;
    PrintWriter out;
    FastScanner sc;

    static Throwable uncaught;

    public void run() {
        try {
            if (file) {
                in = new BufferedReader(new FileReader("strings.in"));
                out = new PrintWriter(new FileWriter("strings.out"));
            } else {
                in = new BufferedReader(new InputStreamReader(System.in));
                out = new PrintWriter(System.out);
            }
            sc = new FastScanner(in);
            solve();
        } catch (Throwable t) {
            Main.uncaught = t;
        } finally {
            out.close();
        }
    }

    public static void main(String[] args) throws Throwable {
        Thread t = new Thread(null, new Main(), "", 128 * 1024 * 1024);
        t.start();
        t.join();
        if (uncaught != null) {
            throw uncaught;
        }
    }

}

class FastScanner {

    BufferedReader reader;
    StringTokenizer strTok;

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

    public String nextToken() throws IOException {
        while (strTok == null || !strTok.hasMoreTokens()) {
            strTok = new StringTokenizer(reader.readLine());
        }
        return strTok.nextToken();
    }

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

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

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

}


import java.util.*;

public class B
{
   public static void main(String[] args)
   {
      new B(new Scanner(System.in));
   }

   int oo = 987654321;

   int[][] grid;
   int W;
   int H;

   boolean check(int x, int y)
   {
      if (x < 0) return false;
      if (y < 0) return false;
      if (x >= W) return false;
      if (y >= H) return false;
      return true;
   }

   boolean isWall(int x, int y)
   {
      if (!check(x+1, y+1)) return true;
      if (!check(x-1, y+1)) return true;
      if (!check(x+1, y-1)) return true;
      if (!check(x-1, y-1)) return true;
      return false;
   }

   void add(ArrayDeque<Node> q, int x, int y, int d)
   {
      if (!check(x, y)) return;
      if (grid[x][y] <= d) return;
      q.add(new Node(x, y, d));
   }

   void bfs()
   {
      for (int[] gri : grid)
         Arrays.fill(gri, oo);

      ArrayDeque<Node> q = new ArrayDeque<Node>();
      for (int j=0; j<H; j++)
         for (int i=j%2; i<W; i+=2)
            if (isWall(i, j))
               q.add(new Node(i, j, 1));

      while (q.size() > 0)
      {
         Node cur = q.poll();
         if (grid[cur.x][cur.y] <= cur.d) continue;
         grid[cur.x][cur.y] = cur.d;

         add(q, cur.x+1, cur.y+1, cur.d+1);
         add(q, cur.x-1, cur.y+1, cur.d+1);
         add(q, cur.x+1, cur.y-1, cur.d+1);
         add(q, cur.x-1, cur.y-1, cur.d+1);
      }
   }

   public B(Scanner in)
   {
      W = in.nextInt();
      H = in.nextInt();
      grid = new int[W][H];

      int N = in.nextInt();
      bfs();

      int res = 0;
      for (int[] gri : grid)
         for (int v : gri)
            if (v == N)
               res++;
      System.out.printf("%d%n", res);

   }
}

class Node
{
   int x, y, d;

   public Node(int xx, int yy, int dd)
   {
      x=xx; y=yy; d=dd;
   }
}


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

public class Main {

	MyScanner in;
	PrintWriter out;

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

	public void run() throws Exception {
		in = new MyScanner();
		out = new PrintWriter(System.out);

		solve();

		out.close();
	}

	public void solve() throws Exception {
		int n = in.nextInt();
		int m = in.nextInt();
		int x = in.nextInt();

		int l = 1, r = m, t = 1, b = n;
		for (int i = 0; i < x - 1; i++) {
			l++;
			r--;
			t++;
			b--;
		}

		int ans = 0;
		for (int i = l; i <= r; i++) {
			for (int j = t; j <= b; j++) {
				if (((i == l) || (i == r) || (j == t) || (j == b)) && ((i + j) % 2 == 0)) ans++;
			}
		}
		out.println(ans);
	}
}

class MyScanner {
	BufferedReader br;
	StringTokenizer st;

	public MyScanner() throws Exception {
		br = new BufferedReader(new InputStreamReader(System.in));
	}

	String next() throws Exception {
		if ((st == null) || (!st.hasMoreTokens())) {
			st = new StringTokenizer(br.readLine());
		}
		return st.nextToken();
	}

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

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

	boolean nextBoolean() throws Exception {
		return Boolean.parseBoolean(next());
	}

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


import java.util.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;

public class C {

    int INF = 1 << 28;
    long P = 1000000009;

    void run() {
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        String t = sc.next();
        long[][] dp = new long[s.length()][t.length()];
        for(int i=0;i<t.length();i++) if(s.charAt(0) == t.charAt(i)) dp[0][i] = (dp[0][i]+1)%P;
        for(int i=1;i<s.length();i++) {
            long sum = 0;
            for(int j=0;j<t.length();j++) {
                if( s.charAt(i) == t.charAt(j) ) {
                    dp[i][j] = (dp[i][j]+sum+1)%P;
                }
                if(s.charAt(i-1) == t.charAt(j)) sum = (sum+dp[i-1][j])%P;
            }
        }
        long sum = 0;
        for(int i=0;i<s.length();i++) for(int j=0;j<t.length();j++){
            sum = (sum+dp[i][j])%1000000009;
        }
        System.out.println(sum);
    }

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


import java.util.Arrays;
import java.util.Scanner;

public class C {
    static int[][] next;
    static int[][] dp;
    static char[] s, t;

    static int mod = 1000000007;

    static int solve(int sIdx, int tIdx) {
        if (sIdx == s.length || tIdx == t.length)
            return 1;
        if (dp[sIdx][tIdx] != -1)
            return dp[sIdx][tIdx];
        long res = 0;
        if (next[tIdx][s[sIdx] - 'a'] != -1) {
            res = solve(sIdx, next[tIdx][s[sIdx] - 'a']);
            if (sIdx < s.length - 1 && (next[tIdx][s[sIdx + 1] - 'a'] != -1)) {
                res = ((res + 1) % mod + solve(sIdx + 1,
                        next[tIdx][s[sIdx + 1] - 'a']))
                        % mod;
            } else {
                res = (res + 1) % mod;
            }
        } else {
            if (sIdx < s.length - 1 && (next[tIdx][s[sIdx + 1] - 'a'] != -1)) {
                res = ((res + 1) % mod + solve(sIdx + 1,
                        next[tIdx][s[sIdx + 1] - 'a']))
                        % mod;
            } else
                res = (res + 1) % mod;
        }
        return dp[sIdx][tIdx] = (int) (res % mod);
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        s = sc.next().toCharArray();
        t = sc.next().toCharArray();
        next = new int[t.length][26];
        dp = new int[s.length][t.length];
        for (int i = 0; i < s.length; i++)
            Arrays.fill(dp[i], -1);
        for (int i = 0; i < t.length; i++)
            Arrays.fill(next[i], -1);
        for (int i = 0; i < t.length; i++) {
            for (int j = i + 1; j < t.length; j++) {
                if (next[i][t[j] - 'a'] == -1) {
                    next[i][t[j] - 'a'] = j;
                }
            }
        }
        long res = 0;
        for (int i = 0; i < s.length; i++) {
            for (int j = 0; j < t.length; j++) {
                if (s[i] == t[j]) {
                    res = (res + solve(i, j)) % mod;
                    break;
                }
            }
        }
        System.out.println(res);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner r = new Scanner(System.in);

        a = r.next().toCharArray();
        b = r.next().toCharArray();

        DP = new int[a.length + 1][b.length + 1];
        for(int[] i : DP)
            Arrays.fill(i, -1);

        int ret = 0;
        for(int s = 0; s < a.length; s++){
            ret += go(s, 0);
        }

        System.out.println(ret);
    }
    static char[] a, b;
    static int[][] DP;
    static int mod = 1000000007;
    private static int go(int i, int j) {
        if(i >= a.length || j >= b.length) return 0;

        if(DP[i][j] != -1)return DP[i][j];

        if(a[i] == b[j]){
            return DP[i][j] = 1 + go(i + 1, j + 1) + go(i, j + 1);
        }else{
            return DP[i][j] = go(i, j + 1);
        }
    }
}


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner r = new Scanner(System.in);

        a = r.next().toCharArray();
        b = r.next().toCharArray();

        DP = new int[a.length + 1][b.length + 1];

        int ret = 0;
        for(int s = 0; s < a.length; s++){
            ret += go(s, 0);
        }

        System.out.println(ret);
    }
    static char[] a, b;
    static int[][] DP;
    static int mod = 1000000007;
    private static int go(int i, int j) {
        if(i >= a.length || j >= b.length) return 0;

        if(a[i] == b[j]){
            return DP[i][j] = (int) (((long)1 + go(i + 1, j + 1) + go(i, j + 1)) % mod);
        }else{
            return DP[i][j] = go(i, j + 1);
        }
    }
}


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

public class main {

	public static long f[];
	public static int n;
	public static long k;

	public static void main(String[] args) {
		Scanner reader = new Scanner(System.in);
		f = new long[55];
		f[0] = 1;
		f[1] = 1;
		for (int i = 2; i <= 50; i++)
			f[i]  = f[i - 1] + f[i - 2];

		n = reader.nextInt();
		k = reader.nextLong();

		int m = 1;
		while (true){
			if (k <= f[n - 1]){
				System.out.print(m + " ");
				n--;
				m++;
			}
			else{
				k -= f[n - 1];
				System.out.print((m + 1) + " " + m + " ");
				m += 2;
				n -= 2;
			}
			if (n == 1){
				break;
			}
			if (n == 0) break;
		}
	}

}


import java.io.*;
import java.util.*;
public class cf3092D{
	static int n, k;
	static int[] fib;
	static ArrayDeque<Integer> list = new ArrayDeque<Integer>();

    public static void main(String[] args) throws IOException {
    	Scanner f = new Scanner(System.in);
        StringTokenizer st = new StringTokenizer(f.nextLine());
        n = Integer.parseInt(st.nextToken());
        k = Integer.parseInt(st.nextToken());
        fib = new int[51];
        fib[0] = 1;
        fib[1] = 1;
        f.close();
        for(int i = 2; i < 51; i++){
        	fib[i] = fib[i-1] + fib[i-2];
        }

        act(n-1);
        String ans = "";
        for(int i = 1; i <= n; i++){
        	int num = list.poll();
        	if(num == 1){
        		ans += (i+1) + " " + i + " ";
        		i++;
        	}
        	else{
        		ans += i + " ";
        	}
        }

        ans = ans.substring(0, ans.length()-1);
        System.out.println(ans);
    }

    static void act(int i){
    	if(i > -1){
    		if(k <= fib[i]){
	    		list.add(0);
	    		act(i-1);
	    	}
	    	else{
	    		list.add(1);
	    		k -= fib[i];
	    		act(i-2);
	    	}
    	}
    }
}


import java.util.*;
import java.io.PrintWriter;
public class a
{
	public static void main(String[] arg)
	{
		new a();
	}
	long MOD = 1_000_000_007;
	long[][] memo;
	long[] fib;
	public a()
	{
		Scanner in = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int n = in.nextInt();
		long k = in.nextLong();
		int[] arr = new int[n];
		for(int i = 1; i <= n; i++) arr[i-1] = i;
		fib = new long[n+1];
		fib[0] = 1;
		fib[1] = 1;
		for(int i = 2; i < fib.length; i++) fib[i] = fib[i-1] + fib[i-2];
		int index = 0;
		while(k > 1)
		{
			if(k <= fib[n-index-1])
				index++;
			else
			{
				k -= fib[n-index-1]+1;
				swap(arr, index, index+1);
			}
		}
		for(int v : arr) out.print(v + " ");
		in.close();
		out.close();
	}
	void swap(int[] arr, int i, int j)
	{
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}

}


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Aldo Culquicondor
 */
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);
		TaskB solver = new TaskB();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskB {
    void move(int[] A, int start, int end) {
        int tmp = A[end-1];
        for (int i = start; i < end - 1; ++i)
            A[i + 1] = A[i];
        A[start] = tmp;
    }
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int n = in.nextInt();
        long k = (1L << n - 1) - in.nextLong();
        int[] A = new int[n];
        for (int i = 0; i < n; ++i)
            A[i] = i + 1;
        int[] C = new int[n];
        int sz = 1;
        for (int i = 1; i < n; ++i) {
            if ((k & (1L << n - i - 1)) != 0)
                C[sz++] = i;
        }
        for (int i = 0; i < sz - 1; ++i)
            move(A, C[i], C[i+1]);
        IOUtils.printArray(out, A);
        out.println();
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer tokenizer;
    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }
    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }
    public int nextInt() {
        return Integer.parseInt(next());
    }
    public long nextLong() {
        return Long.parseLong(next());
    }
}

class IOUtils {
    public static void printArray(PrintWriter out, int A[], int start, int end) {
        out.print(A[0]);
        for (int i = start + 1; i < end; ++i)
            out.printf(" %d", A[i]);
    }
    public static void printArray(PrintWriter out, int A[]) {
        printArray(out, A, 0, A.length);
    }
}


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

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int mod=998244353;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        int n=in.nextInt(),k=in.nextInt(),l=in.nextInt();
        long[]fac=new long[n+1];
        fac[0]=1;
        for(int i=1;i<=n;i++){
            fac[i]=fac[i-1]*i%mod;
        }
        long[][]dp=new long[2*n+1][2*n+2];
        dp[0][0]=1;
        for(int i=1;i<=2*n;i++){
            for(int j=0;j<=i;j++){
                if(j>0) dp[i][j]=(dp[i][j]+dp[i-1][j-1])%mod;
                dp[i][j]=(dp[i][j]+dp[i-1][j+1]*(j+1)%mod)%mod;
            }
        }
        long ans=0;
        for(int i=k;i<=2*n;i++){
            for(int j=k;j<=n;j++){
                ans=(ans+dp[i][j]*dp[2*n-i][j]%mod*fac[j]%mod)%mod;
            }
        }
        out.println(l*ans%mod*Pow(dp[2*n][0],mod-2)%mod*Pow(2*n+1,mod-2)%mod);
        out.flush();
    }
    long Pow(long a,long b){
        long ans=1;
        while(b>0){
            if((b&1)!=0)ans=(ans*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ans;
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }
}


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

public class Codeforces1153F {

	public static void main(String[] args) throws IOException {
		int P = 998244353;

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int real_k = Integer.parseInt(st.nextToken());
		int l = Integer.parseInt(st.nextToken());

		//generate factorials
		int[] factorials = new int[2*n+2];
		factorials[0] = 1;
		for (int i = 1; i <= 2*n+1; i++) {
			factorials[i] = multiply(factorials[i-1], i, P);
		}

		//number of ways to choose k pairs from 2k elements
		//where order doesn't matter
		//equals (2k)!/(2^n)/k! = (2k-1)!!
		int[] doublefact = new int[n+1];
		doublefact[0] = 1;
		for (int i = 1; i <= n; i++) {
			doublefact[i] = multiply(doublefact[i-1], (2*i-1), P);
		}

		//list[r][k] stores for rth segment, exactly k of the n segments covering it
		int[][] list = new int[2*n+2][n+1];

		for (int r = 1; r <= 2*n+1; r++) {
			for (int k = 1; k <= n; k++) {
				if (((r%2) != (k%2)) && (r-1 >= k) && (2*n+1-r >= k)) {
					int num = multiply(factorials[r-1], factorials[2*n+1-r], P);
					num = multiply(num, doublefact[(r-k-1)/2], P);
					num = multiply(num, doublefact[(2*n+1-r-k)/2], P);

					int denom = multiply(factorials[r-k-1], factorials[2*n+1-r-k], P);
					denom = multiply(denom, factorials[k], P);

					list[r][k] = multiply(num, inverse(multiply(denom, doublefact[n], P), P), P);
				}

			}
		}

		int ans = 0;
		for (int r = 1; r <= 2*n+1; r++) {
			for (int k = real_k; k <= n; k++) {
				ans += list[r][k];
				ans %= P;
			}
		}

		ans = multiply(ans, l, P);
		ans = multiply(ans, inverse(2*n+1, P), P);

		System.out.println(ans);

	}

	public static int multiply (int a, int b, int n) {
		long ab = (long) a * (long) b;
		return ((int) (ab%n));
	}

	public static int inverse (int a, int n) {
		int m = n;
		int r1 = 1;
		int r2 = 0;
		int r3 = 0;
		int r4 = 1;
		while ((a > 0) && (n > 0)) {
			if (n >= a) {
				r3 -= r1*(n/a);
				r4 -= r2*(n/a);
				n = n%a;
			}
			else {
				int tmp = a;
				a = n;
				n = tmp;
				tmp = r1;
				r1 = r3;
				r3 = tmp;
				tmp = r2;
				r2 = r4;
				r4 = tmp;
			}
		}
		if (a == 0) {
			if (r3 >= 0)
				return (r3%m);
			else
				return (m+(r3%m));
		}
		else {
			if (r1 >= 0)
				return (r1%m);
			else
				return (m+(r1%m));
		}

	}

}


package Contest551;

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

public class mainF {
    public static Scanner enter = new Scanner(System.in);
    public static PrintWriter out = new PrintWriter(System.out);
    public static long mod=998244353;
    public static long cnk[][]=new long[(int)2e3+1][(int)2e3+1];
    public static long fact[]=new long[2*(int)2e3+1];
    public static long reverse[]=new long[2*(int)2e3+1];
    public static long deg_2[]=new long[(int)2e3+1];
    public static void main(String[] args) {
        long t=System.currentTimeMillis();
        cnk[0][0]=1;
        for (int i = 1; i <cnk.length ; i++) {
            cnk[0][i]=1;
            for (int j = 1; j <=i ; j++) {
                cnk[j][i]=cnk[j-1][i-1]+cnk[j][i-1];
                cnk[j][i]%=mod;
            }
        }
        fact[0]=1;
        deg_2[0]=1;
        for (int i = 1; i <fact.length ; i++) {
            fact[i]=fact[i-1]*i;
            fact[i]%=mod;
        }
        for (int i = 1; i <deg_2.length ; i++) {
            deg_2[i]=deg_2[i-1]*2;
            deg_2[i]%=mod;
        }
        reverse[1]=1;
        for (int i = 3; i <reverse.length ; i+=2) {
            reverse[i]=bin_pow(fact[i],mod-2,mod);
        }
       /* System.out.println(Arrays.toString(reverse));
        System.out.println(fact[5]);
        System.out.println(reverse[5]);*/
        int n=enter.nextInt();
        int k=enter.nextInt();
        long l=enter.nextInt();
        l%=mod;
        long ans=0;
        for (int i = k; i <=n ; i++) {
            long tmp=0;
            for (int s = 0,c=1; s <=n-i ; s++,c*=-1) {
                long a=1;
                a*=cnk[s][n-i]*deg_2[s];
                a%=mod;
                a*=fact[s+i];
                a%=mod;
                a*=fact[s+i];
                a%=mod;
                a*=reverse[2*(s+i)+1];
                a%=mod;
                tmp+=a*c;
                tmp%=mod;
               // System.out.println(reverse[2*(s+i)+1]);
            }
            //System.out.println(tmp);
            /*ans+=cnk[i][n]*deg_2[i]*tmp;
            ans%=mod;*/
            long  b=1;
            b*=tmp*deg_2[i];
            b%=mod;
            //System.out.println(b);
            b*=cnk[i][n];
            b%=mod;
            ans+=b;
            ans%=mod;
        }
        ans*=l;
        ans%=mod;
        System.out.println((ans<0)? (ans+mod) : ans);

      //  System.out.println(System.currentTimeMillis()-t);

    }
    public static long bin_pow(long a,long b, long mod){//a^b %mod
        long ans=1;
        while(b!=0){
            if((b&1)==1) ans*=a;
            a*=a;
            ans%=mod;
            a%=mod;
            b>>=1;
        }
        return ans;
    }
}


//package Contest551;

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

public class mainF {
    public static Scanner enter = new Scanner(System.in);
    public static PrintWriter out = new PrintWriter(System.out);
    public static long mod=998244353;
    public static long cnk[][]=new long[(int)2e3+1][(int)2e3+1];
    public static long fact[]=new long[2*(int)2e3+1];
    public static long reverse[]=new long[2*(int)2e3+1];
    public static long deg_2[]=new long[(int)2e3+1];
    public static void main(String[] args) {
        long t=System.currentTimeMillis();
        cnk[0][0]=1;
        for (int i = 1; i <cnk.length ; i++) {
            cnk[0][i]=1;
            for (int j = 1; j <=i ; j++) {
                cnk[j][i]=cnk[j-1][i-1]+cnk[j][i-1];
                cnk[j][i]%=mod;
            }
        }
        fact[0]=1;
        deg_2[0]=1;
        for (int i = 1; i <fact.length ; i++) {
            fact[i]=fact[i-1]*i;
            fact[i]%=mod;
        }
        for (int i = 1; i <deg_2.length ; i++) {
            deg_2[i]=deg_2[i-1]*2;
            deg_2[i]%=mod;
        }
        reverse[1]=1;
        for (int i = 3; i <reverse.length ; i+=2) {
            reverse[i]=bin_pow(fact[i],mod-2,mod);
        }
       /* System.out.println(Arrays.toString(reverse));
        System.out.println(fact[5]);
        System.out.println(reverse[5]);*/
        int n=enter.nextInt();
        int k=enter.nextInt();
        long l=enter.nextInt();
        l%=mod;
        long ans=0;
        for (int i = k; i <=n ; i++) {
            long tmp=0;
            for (int s = 0,c=1; s <=n-i ; s++,c*=-1) {
                long a=1;
                a*=cnk[s][n-i]*deg_2[s];
                a%=mod;
                a*=fact[s+i];
                a%=mod;
                a*=fact[s+i];
                a%=mod;
                a*=reverse[2*(s+i)+1];
                a%=mod;
                tmp+=a*c;
                tmp%=mod;
               // System.out.println(reverse[2*(s+i)+1]);
            }
            //System.out.println(tmp);
            /*ans+=cnk[i][n]*deg_2[i]*tmp;
            ans%=mod;*/
            long  b=1;
            b*=tmp*deg_2[i];
            b%=mod;
            //System.out.println(b);
            b*=cnk[i][n];
            b%=mod;
            ans+=b;
            ans%=mod;
        }
        ans*=l;
        ans%=mod;
        System.out.println((ans<0)? (ans+mod) : ans);

      //  System.out.println(System.currentTimeMillis()-t);

    }
    public static long bin_pow(long a,long b, long mod){//a^b %mod
        long ans=1;
        while(b!=0){
            if((b&1)==1) ans*=a;
            a*=a;
            ans%=mod;
            a%=mod;
            b>>=1;
        }
        return ans;
    }
}


/**
 * Created by evgeniyradchenko on 11/28/17.
 */
public class Main {

    private static int NMAX = 22;
    private static long a[] = new long[NMAX];
    private static boolean c[] = new boolean[NMAX + 1];
    private static int d[] = new int[NMAX + 1];

    public static void main(String[] args) throws Exception {
        Scanner s = new Scanner(System.in);

        int n = s.nextInt();
        for (int i = 0; i < n; ++i) {
            a[i] = s.nextInt();
        }

        if (n == 1) {
            System.out.println(-1);
            return;
        }

        generate(n, 0, 0, 0);
    }

    private static boolean generate(int n, int cur, long s1, long s2) {
        if (cur == n - 1) {
            for (int i = 1; i <= n; ++i)
                if (!c[i]) {
                    d[n - 1] = i;
                }
            for (int i = 0; i < n; ++i) {
                System.out.print(a[d[i] - 1] + " ");
            }

            return true;
        }

        boolean isOk = false;
        for (int i = 1; i <= n && !isOk; ++i)
            if (!c[i] && s1 + cur + 1 !=  s2 + i) {
                d[cur] = i;
                c[i] = true;
                isOk = generate(n, cur + 1, s1 + cur + 1, s2 + i);
                c[i] = false;
            }

        return isOk;
    }

}


import java.io.*;
import java.util.*;
public class D {
	public static void main(String[] args)throws Throwable {
		MyScanner sc=new MyScanner();
		PrintWriter pw=new PrintWriter(System.out);

		n=sc.nextInt();
		if(n==1){
			System.out.println(sc.next());
			return;
		}
		a=new int [n];
		for(int i=0;i<n;i++){
			a[i]=sc.nextInt();
			sum+=a[i];
		}
		b=new int [n];

		allA=new long [1<<n];
		allB=new long [1<<n];
		for(int msk=0;msk<(1<<n);msk++){
			long sum=0;
			for(int i=0;i<n;i++)
				if((msk & (1<<i))!=0)
					sum+=a[i];
			allA[msk]=sum;
		}

		go(0,0,1);

		if(!done)
			pw.println(-1);
		else
			for(int x : c)
				pw.print(x+" ");

		pw.flush();
		pw.close();
	}
	static long sum;
	static long [] allA,allB;
	static boolean done;
	static int [] c;
	static int n;
	static int [] a,b;

	static void go(int i,int msk,int p){
		if(done)
			return;
		if(i==n){
			done=true;
			c=Arrays.copyOf(b, n);
			return;
		}
		toto : for(int j=0;j<n && !done;j++){
			if(a[i]==a[j])
				continue toto;
			if((msk & (1<<j))==0){
				b[i]=a[j];
				for(int idx=p;idx<2*p;idx++){
					allB[idx]=allB[idx-p]+a[j];
					if(allB[idx]==allA[idx] && idx!=(1<<n)-1)
						continue toto;
				}
				go(i+1, msk | (1<<j),p*2);
			}
		}
	}

	static class MyScanner {
		BufferedReader br;
		StringTokenizer st;
		public MyScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}
		String next() {while (st == null || !st.hasMoreElements()) {
			try {st = new StringTokenizer(br.readLine());}
			catch (IOException e) {e.printStackTrace();}}
		return st.nextToken();}
		int nextInt() {return Integer.parseInt(next());}
		long nextLong() {return Long.parseLong(next());}
		double nextDouble() {return Double.parseDouble(next());}
		String nextLine(){String str = "";
		try {str = br.readLine();}
		catch (IOException e) {e.printStackTrace();}
		return str;}
	}
}