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][5][5];
        long[][][] dp2 = new long[2][5][5];
        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[i + 3][i + 3];
            long[][] naft = new long[i + 3][i + 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] + 10000000L * m) % m;
                    naft[len][ind] = (naft[len][ind] + naft[len][ind - 1] + 10000000L * 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;
        }
    }
    //--------------------------------------------------------
}


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]=1l;
			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(); }

	}
}


/*
bts songs to dance to:
I need U
Run
ON
Filter
I'm fine
 */
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.abs;
import static java.lang.System.out;
import java.util.*;
import java.io.*;
import java.math.*;

public class x1515E
{
    static long MOD;
    public static void main(String hi[]) throws Exception
    {
        BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(infile.readLine());
        int N = Integer.parseInt(st.nextToken());
        MOD = Long.parseLong(st.nextToken());
        fac = new long[401];
        invfac = new long[401];
        fac[0] = invfac[0] = 1L;
        for(int i=1; i <= 400; i++)
        {
            fac[i] = (fac[i-1]*i)%MOD;
            invfac[i] = power(fac[i], MOD-2, MOD);
        }
        long[] pow2 = new long[401];
        for(int i=0; i <= 400; i++)
            pow2[i] = power(2, i, MOD);
        long[][] dp = new long[N+1][N+1];
        for(int v=1; v <= N; v++)
        {
            dp[v][v] = pow2[v-1];
            for(int k=1; k <= v; k++)
                for(int block=1; block <= k; block++)
                {
                    if(block == v)
                        continue;
                    long temp = (dp[v-block-1][k-block]*calc(k-block, block))%MOD;
                    temp = (temp*pow2[block-1])%MOD;
                    dp[v][k] += temp;
                    if(dp[v][k] >= MOD)
                        dp[v][k] -= MOD;
                }
        }
        long res = 0L;
        for(int v=1; v <= N; v++)
        {
            res += dp[N][v];
            if(res >= MOD)
                res -= MOD;
        }
        System.out.println(res);
    }
    static long[] fac, invfac;
    public static long calc(int a, int b)
    {
        long res = (fac[a+b]*invfac[a])%MOD;
        return (res*invfac[b])%MOD;
    }
    public static long power(long x, long y, long p)
    {
        //0^0 = 1
        long res = 1L;
        x = x%p;
        while(y > 0)
        {
            if((y&1)==1)
                res = (res*x)%p;
            y >>= 1;
            x = (x*x)%p;
        }
        return res;
    }
}


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

public class E {

	static long mod;
	static long[][] dp;
	static int n;
	static long[] nWaysToPlaceGroupOfSize;

	public static void main(String[] args) {
		FastScanner fs=new FastScanner();
		n=fs.nextInt();
		mod=fs.nextInt();
		precomp();
		dp=new long[n+1][n+1];
		for (int i=0; i<dp.length; i++) Arrays.fill(dp[i], -1);

		long ans=0;
		for (int nXsLeft=2; nXsLeft<=n; nXsLeft++) {
			long curAns=go(0, nXsLeft);
			ans=add(ans, curAns);
		}
		System.out.println(ans);
	}

	static long go(int position, int nXsLeft) {
		if (position==n) {
			//last thing was skipped, impossible
			return 0;
		}
		if (position==n+1) {
			//last thing was included, 1 way of doing that
			if (nXsLeft==0) return 1;
			return 0;
		}
		if (dp[position][nXsLeft]!=-1) {
			return dp[position][nXsLeft];
		}
		//TODO: brute force number of xs to place
		long ways=0;
		for (int nPlace=1; nPlace<=Math.min(nXsLeft, n-position); nPlace++) {
			long futureWays=go(position+nPlace+1, nXsLeft-nPlace);
			long waysToPlaceMe=nCk(nXsLeft, nPlace);
			if (nPlace>1) waysToPlaceMe=mul(waysToPlaceMe, nWaysToPlaceGroupOfSize[nPlace]);
			ways=add(ways, mul(waysToPlaceMe, futureWays));
		}
		return dp[position][nXsLeft]=ways;
	}

	static long nCk(int n, int k) {
		if (k>n) throw null;
		return mul(facts[n], mul(factInvs[k], factInvs[n-k]));
	}

	static long add(long a, long b) {
		return (a+b)%mod;
	}
	static long sub(long a, long b) {
		return ((a-b)%mod+mod)%mod;
	}
	static long mul(long a, long b) {
		return (a*b)%mod;
	}
	static long fastPow(long base, long e) {
		if (e==0) return 1;
		long half=fastPow(base, e/2);
		if (e%2==0) return mul(half, half);
		return mul(half, mul(half, base));
	}

	static long[] facts=new long[1_000_00];
	static long[] factInvs=new long[1_000_00];
	static void precomp() {
		facts[0]=1;
		for (int i=1; i<facts.length; i++) facts[i]=mul(facts[i-1], i);
		for (int i=0; i<factInvs.length; i++) factInvs[i]=fastPow(facts[i], mod-2);
		nWaysToPlaceGroupOfSize=new long[500];
		for (int finalSize=1; finalSize<nWaysToPlaceGroupOfSize.length; finalSize++) {
			for (int firstPos=0; firstPos<finalSize; firstPos++) {
				int l=firstPos, r=finalSize-1-firstPos;
				nWaysToPlaceGroupOfSize[finalSize]=add(nWaysToPlaceGroupOfSize[finalSize], nCk(l+r, l));
			}
		}
		System.err.println("Done with precomp.");
	}

	static void sort(int[] a) {
		ArrayList<Integer> l=new ArrayList<>();
		for (int i:a) l.add(i);
		Collections.sort(l);
		for (int i=0; i<a.length; i++) a[i]=l.get(i);
	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

}


import java.io.*;

public class E14G {
    static int[][] choose;
    public static void main(String[] args) throws IOException {
        init_io();
        int N = nint(), M = nint();
        choose = new int[N+1][];
        long[] ways = new long[N+1];
        ways[0] = 1; ways[1] = 1;
        for (int i = 0; i <= N; i++) choose[i] = new int[i+1];
        for (int i = 0; i <= N; i++) {
            choose[i][0] = choose[i][i] = 1;
            for (int j = 1; j < i; j++) {
                choose[i][j] = (choose[i-1][j-1] + choose[i-1][j]) % M;
            }
        }
        for (int i = 2; i <= N; i++) {
            for (int j = 0; j < i; j++) {
                ways[i] = (ways[i] + choose[i-1][j]) % M;
            }
        }
        long[][] dp = new long[(N+1)/2+1][N+1];
        dp[0][0] = 1;
        for (int i = 1; i <= (N+1)/2; i++) {
            for (int j = 1; j <= N; j++) {
                for (int k = 1; k <= j; k++) {
                    dp[i][j] = (dp[i][j] + ways[k] * choose[j][k] % M * dp[i-1][j-k] % M) % M;
                }
            }
        }
        long ans = 0;
        for (int i = 1; i <= (N+1)/2; i++) {
            ans = (ans + dp[i][N-(i-1)]) % M;
        }
        out.println(ans);
        out.close();
    }

    static StreamTokenizer in;
    static PrintWriter out;
    static BufferedReader br;

    static int nint() throws IOException {
        in.nextToken();
        return (int) in.nval;
    }

    static void init_io() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        in = new StreamTokenizer(br);
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    }
}


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

public class CF1515E extends PrintWriter {
	CF1515E() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF1515E o = new CF1515E(); o.main(); o.flush();
	}

	void main() {
		int n = sc.nextInt();
		int md = sc.nextInt();
		int k = (n + 1) / 2;
		int[][] dp = new int[k + 1][n + 1]; dp[0][0] = 1;
		for (int h = 1; h <= k; h++)
			for (int l = h; l <= n - h + 1; l++)
				dp[h][l] = (int) ((dp[h][l - 1] * 2L + dp[h - 1][l - 1]) * h % md);
		int ans = 0;
		for (int h = 1; h <= k; h++)
			ans = (ans + dp[h][n - h + 1]) % md;
		println(ans);
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

@SuppressWarnings("unused")
public class Solution{

	static long mod = -1;
	static long[] fact, invfact, pow;
	static long[][] C;
	static long[][] dp;
	static final int N = 405;
	static int n;

	public static void main(String[] args) throws IOException {
		FastScanner fs = new FastScanner();
    	PrintWriter out = new PrintWriter(System.out);

    	int tt = 1;
    	outer:
    	while(tt-->0) {

    		n = fs.nextInt();
    		mod = fs.nextLong();

    		dp = new long[N][N];
    		precompute();

    		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]*pow[k-1])%mod)*C[j+k][k])%mod;
    					dp[i+k+1][j+k] %= mod;
    				}
    			}
    		}

    		long ans = 0;
    		for(int i=0;i<=n;i++) {
    			ans = (ans + dp[n+1][i])%mod;
    		}

    		out.println(ans);

    	}

    	out.close();
    }

	static void precompute() {
		fact = new long[N]; invfact = new long[N]; C = new long[N][N]; pow = new long[N];
		fact[0] = 1;
		for(int i=1;i<=n;i++) fact[i] = (fact[i-1]*i)%mod;
		invfact[n] = inv(fact[n]);
		for(int i=n-1;i>=0;i--) invfact[i] = (invfact[i+1]*(i+1))%mod;

		pow[0] = 1;
		for(int i=1;i<=n;i++) pow[i] = (pow[i-1]*2)%mod;

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

	}

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

	static long inv(long n) {
		return exp(n, mod-2);
	}

    static final Random random=new Random();

    static <T> void shuffle(T[] arr) {
    	int n = arr.length;
    	for(int i=0;i<n;i++	) {
    		int k = random.nextInt(n);
    		T temp = arr[k]; arr[k] = arr[i]; arr[i] = temp;
    	}
    }

    static void ruffleSort(int[] a) {
    	int n=a.length;//shuffle, then sort
    	for (int i=0; i<n; i++) {
    		int oi=random.nextInt(n); int temp=a[oi];
    		a[oi]=a[i]; a[i]=temp;
    	}
    	Arrays.sort(a);
    }

    static void ruffleSort(long[] a) {
    	int n=a.length;//shuffle, then sort
    	for (int i=0; i<n; i++) {
    		int oi=random.nextInt(n); long temp=a[oi];
    		a[oi]=a[i]; a[i]=temp;
    	}
    	Arrays.sort(a);
    }

    static void reverse(int[] arr, int l, int r) {
    	for(int i=l;i<l+(r-l)/2;i++){
    		int temp = arr[i]; arr[i] = arr[r-i+l-1]; arr[r-i+l-1] = temp;
    	}
    }

    static void reverse(long[] arr, int l, int r) {
    	for(int i=l;i<l+(r-l)/2;i++){
    		long temp = arr[i]; arr[i] = arr[r-i+l-1]; arr[r-i+l-1] = temp;
    	}
    }

    static <T> void reverse(T[] arr, int l, int r) {
    	for(int i=l;i<l+(r-l)/2;i++) {
    		T temp = arr[i]; arr[i] = arr[r-i+l-1]; arr[r-i+l-1] = temp;
    	}
    }

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

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

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

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

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

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

    	public char nextChar() {
    		return next().toCharArray()[0];
    	}
    }

}


// Don't place your source in a package
import javax.swing.*;
import java.lang.reflect.Array;
import java.text.DecimalFormat;
import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
import java.util.stream.Stream;

// Please name your class Main
public class Main {
    static FastScanner fs=new FastScanner();
    static class FastScanner {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer("");
        public String next() {
            while (!st.hasMoreElements())
                try {
                    st=new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return st.nextToken();
        }
        int Int() {
            return Integer.parseInt(next());
        }

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

        String Str(){
            return next();
        }
    }

    public static void main (String[] args) throws java.lang.Exception {
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

        int T=1;
        for(int t=0;t<T;t++){
            int n=Int(),m=Int();

            Solution sol=new Solution(out);
            sol.solution(n,m);
        }
        out.close();

    }

    public static int Int(){
        return fs.Int();
    }
    public static long Long(){
        return fs.Long();
    }
    public static String Str(){
        return fs.Str();
    }

}

class Solution{
    PrintWriter out;
    public Solution(PrintWriter out){
        this.out=out;
    }

    public void solution(int n,int mod){
        long res=0;
        long ncr[][]=new long[501][501];
        long pow[]=new long[501];
        pow[0]=1;
        for(int i=1;i<pow.length;i++){
            pow[i]=(pow[i-1]*2)%mod;
        }

        ncr[0][0]=1;
        for (int i=1;i<ncr.length;i++) {
            ncr[i][0]=1;
            for (int j=1;j<ncr[0].length;j++) {
                ncr[i][j]=(ncr[i-1][j]+ncr[i-1][j-1])%mod;
            }
        }

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

        for(int i=1;i<dp.length;i++){
            dp[i][i]=pow[i-1];
            for(int j=1;j<i;j++){
                for(int k=1;k<i;k++){
                    //pow[cnt-1]
                    if(i-k-1>=1&&j>=k){
                        dp[i][j]=dp[i][j]+dp[i-k-1][j-k]*((ncr[j][k]*pow[k-1])%mod);
                        dp[i][j]%=mod;
                    }
                }

            }
        }

        for(int i=1;i<=n;i++){
            res+=dp[n][i];
            res%=mod;
        }
        out.println(res);
    }

}

/*
                             ;\
                            |' \
         _                  ; : ;
        / `-.              /: : |
       |  ,-.`-.          ,': : |
       \  :  `. `.       ,'-. : |
        \ ;    ;  `-.__,'    `-.|
         \ ;   ;  :::  ,::'`:.  `.
          \ `-. :  `    :.    `.  \
           \   \    ,   ;   ,:    (\
            \   :., :.    ,'o)): ` `-.
           ,/,' ;' ,::"'`.`---'   `.  `-._
         ,/  :  ; '"      `;'          ,--`.
        ;/   :; ;             ,:'     (   ,:)
          ,.,:.    ; ,:.,  ,-._ `.     \""'/
          '::'     `:'`  ,'(  \`._____.-'"'
             ;,   ;  `.  `. `._`-.  \\
             ;:.  ;:       `-._`-.\  \`.
              '`:. :        |' `. `\  ) \
      -hrr-      ` ;:       |    `--\__,'
                   '`      ,'
                        ,-'

                      free bug dog
*/


// Main Code at the Bottom
import java.util.*;
import java.io.*;
public class Main{
	//Fast IO class
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
        public FastReader() {
        	boolean env=System.getProperty("ONLINE_JUDGE") != null;
        	//env=true;
        	if(!env) {
        		try {
					br=new BufferedReader(new FileReader("src\\input.txt"));
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
        	}
        	else 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;
        }
    }
    static long MOD=(long)1e9+7;
    //debug
    static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
    static FastReader sc=new FastReader();
    static PrintWriter out=new PrintWriter(System.out);
    //Global variables and functions
    static long memo[];
    static long C[][];
    static long exp(long a,long x) {
    	if(x==0) return 1;
    	if(x%2==0) return exp((a*a)%MOD,x/2)%MOD;
    	return ((a%MOD)*((exp((a*a)%MOD,x/2))%MOD))%MOD;
    }
    static void fill(int n) {
    	C = new long[n+1][n+1];
    	for(int i = 1; i<=n;i++) C[i][0]=C[i][i]=1;
    	for(int i=2;i<=n;i++) {
    		for(int j=1;j<=n;j++) {
    			C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
    		}
    	}
    }
    //Main function(The main code starts from here)
    public static void main (String[] args) throws java.lang.Exception {
    	int test=1;
    	//test=sc.nextInt();
    	while(test-->0) {
    		int n = sc.nextInt();
    		MOD = sc.nextLong();
    		memo = new long[n+1];
    		fill(n);
    		long dp[][] = new long[n+5][n+5];
    		for(int i=1;i<=n;i++) dp[i][i]=exp(2,i-1);
    		for(int i = 2; i <= n; i++) {
    			for(int j = 1; j < i; j++) {
    				for(int k = 1; k <= j; k++) {
    					long val = (dp[i-k-1][j-k]*C[j][k])%MOD;
    					if(memo[k-1] ==0) memo[k-1] = exp(2, k-1);
    					val=(val*memo[k-1])%MOD;
    					dp[i][j]=(dp[i][j]+val)%MOD;
    				}
    			}
    		}
    		long ans = 0;
    		for(int i=0;i<=n;i++) ans=(ans+dp[n][i])%MOD;
    		out.println(ans);
    	}
        out.flush();
        out.close();
    }
}


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

public class Sol{

static class Pair implements Comparable<Pair>{
        int x;int y;int value;
        public Pair(int x,int y,int value) {

          this.x=x;
          this.y=y;
          this.value=value;
        }
        @Override
        public int compareTo(Pair p){return Long.compare(y,p.y); }

   }

public static void main(String []args){

int t=1;

while(t-->0){
int n=ni();mod=nl();
precomp();
long dp[][]=new long[405][405];dp[0][0]=1l;
for(int i=0;i<n;i++){
    for(int j=0;j<=i;j++){
       for(int k=1;k+i<=n;k++){

          dp[i+k+1][j+k]+=((dp[i][j]*p2[k-1])%mod)*Comb[k+j][k];
          dp[i+k+1][j+k]%=mod;
      }
   }
 }

long sum=0l;
for(int i=0;i<=n;i++)sum=(sum+dp[n+1][i])%mod;
out.println(sum);

}out.close();}

//-----------------Utility--------------------------------------------

static long Comb[][]=new long[405][405];
static long p2[]=new long[405];
static long inv[]=new long[405];
static long factorial[]=new long[405];
static void precomp(){

inv[0]=1;factorial[0]=1l;

for(long i=1;i<405;i++){factorial[(int)i]=i*factorial[(int)i-1];factorial[(int)i]%=mod;}

for(int i=1;i<405;i++){ inv[i]=power(factorial[i],mod-2);}

for(int i=0;i<405;i++){

   for(int j=0;j<=i;j++){
     Comb[i][j]=(((factorial[i]*inv[j])%mod)*inv[i-j])%mod;
   }
 }

for(int i=0;i<405;i++)p2[i]=power(2,i);

}

static int Max=Integer.MAX_VALUE; static long mod=1000000007;
static int v(char c){return (int)(c-'a')+1;}
public static long power(long x, long y )
    {
        //0^0 = 1
        long res = 1L;
        x = x%mod;
        while(y > 0)
        {
            if((y&1)==1)
                res = (res*x)%mod;
            y >>= 1;
            x = (x*x)%mod;
        }
        return res;
    }
//--------------------------------------------------------------------

static InputStream inputStream = System.in;
static OutputStream outputStream = System.out;
static FastReader in=new FastReader(inputStream);
static PrintWriter out=new PrintWriter(outputStream);

static class FastReader
{
  BufferedReader br;
  StringTokenizer st;

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

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

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

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

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

  String nextLine()
  {
      String str = "";
      try
      {
          str = br.readLine();
      }
      catch (IOException e)
      {
          e.printStackTrace();
      }
      return str;
  }
}
static int ni(){return in.nextInt();}
static long nl(){return in.nextLong();}
static String ns(){return in.nextLine();}
static int[] na(int n){int a[]=new int[n];for(int i=0;i<n;i++){a[i]=ni();} return a;}

}


// practice with kaiboy, coached by rainboy
import java.io.*;
import java.util.*;

public class CF1515E extends PrintWriter {
	CF1515E() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF1515E o = new CF1515E(); o.main(); o.flush();
	}

	void main() {
		int n = sc.nextInt();
		int md = sc.nextInt();
		int k = (n + 1) / 2;
		int[][] dp = new int[k + 1][n + 1]; dp[0][0] = 1;
		for (int h = 1; h <= k; h++)
			for (int l = h; l <= n - h + 1; l++)
				dp[h][l] = (int) ((dp[h][l - 1] * 2L + dp[h - 1][l - 1]) * h % md);
		int ans = 0;
		for (int h = 1; h <= k; h++)
			ans = (ans + dp[h][n - h + 1]) % md;
		println(ans);
	}
}


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

public class PhoenixAndComputers {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int mod = Integer.parseInt(st.nextToken());
        long[][] dp = new long[n+2][n+1];
        long[] pow = new long[n+1];
        pow[0] = 1;
        for (int i=1; i <= n; i++){
            pow[i] = pow[i-1]*2;
            pow[i] %= mod;
        }
        long[][] choose = new long[n*2+1][n+1];
        for (int i=0; i <= n; i++){
            choose[i][i] = 1;
        }
        for (int i=1; i <= n*2; i++){
            for (int j=0; j <= n; j++){
                choose[i][j] = choose[i-1][j];
                if (j > 0){
                    choose[i][j] += choose[i-1][j-1];
                }
                choose[i][j] %= mod;
            }
        }
        dp[0][0] = 1;
        for (int i=0; i < n; i++){ // number of computers on
            for (int j=0; j <= i; j++){ // number manually turned on
                for (int k=1; k+i <= n; k++){ // number of computers manually turned on in next "block"
                    dp[i+k+1][j+k] += (pow[k-1] * choose[j+k][k])%mod * dp[i][j];
                    dp[i+k+1][j+k] %= mod;
                }
            }
        }
        long ans = 0;
        for (int j=0; j <= n; j++){
            ans += dp[n+1][j];
            ans %= mod;
        }
        System.out.println(ans);
    }
}


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

public class CF1515E extends PrintWriter {
	CF1515E() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF1515E o = new CF1515E(); o.main(); o.flush();
	}

	int[] ff, gg; int md;
	long ch(int n, int k) {
		return (long) ff[n] * gg[k] % md * gg[n - k] % md;
	}
	long inv(int a) {
		return a == 1 ? 1 : inv(a - md % a) * (md / a + 1) % md;
	}
	void main() {
		int n = sc.nextInt();
		md = sc.nextInt();
		int[] p2 = new int[n];
		for (int p = 1, i = 0; i < n; i++) {
			p2[i] = p;
			p = p * 2 % md;
		}
		ff = new int[n + 1];
		gg = new int[n + 1];
		long f = 1;
		for (int i = 0; i <= n; i++) {
			gg[i] = (int) inv(ff[i] = (int) f);
			f = f * (i + 1) % md;
		}
		int[][] dp = new int[n + 1][n + 1]; dp[1][1] = 1; dp[2][2] = 2;
		for (int u = 3; u <= n; u++)
			for (int v = 1; v <= u; v++) {
				long x = v == u ? p2[u - 1] : 0;
				for (int k = 1; k < v && k <= u - 2; k++)
					x += dp[u - k - 1][v - k] * ch(v, k) % md * p2[k - 1] % md;
				dp[u][v] = (int) (x % md);
			}
		int ans = 0;
		for (int v = 1; v <= n; v++)
			ans = (ans + dp[n][v]) % md;
		println(ans);
	}
}


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

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

        solve(s.nextInt(), s.nextLong());
    }

    public static long inv(long n, long mod) {
        if (n == 1) return 1;
        return (inv(mod % n, mod) * (mod - mod / n)) % mod;
    }

    public static void solve(int n, long mod) {
        long fact[] = new long[n + 2];
        long invFact[] = new long[n + 2];
        long twoPow[] = new long[n + 2];

        fact[0] = 1;
        invFact[0] = 1;
        twoPow[0] = 1;

        for (int i = 1; i < n + 2; i++) {
            fact[i] = (fact[i - 1] * i) % mod;
            invFact[i] = (invFact[i - 1] * inv(i, mod)) % mod;
            twoPow[i] = (2 * twoPow[i - 1]) % mod;
        }

        long dp[][] = new long[n + 2][];
        dp[0] = new long[]{1};

        long next[] = null;
        for (int i = 1; i <= n + 1; i++) {
            next = new long[i + 1];

            for (int j = 0; j < i - 1; j++) {
                for (int k = 0; k < dp[j].length; k++) {
                    next[k + i - j - 1] = (next[k + i - j - 1] + ((((dp[j][k] * twoPow[i - j - 2]) % mod * fact[k + i - j - 1]) % mod * invFact[k]) % mod * invFact[i - j - 1]) % mod) % mod;
                }
            }

            dp[i] = next;
        }

        long sum = 0;
        for (int i = 0; i < next.length; i++) {
            sum = (sum + next[i]) % mod;
        }

        System.out.println(sum);
    }
}


import java.awt.*;
import java.io.*;
import java.sql.Array;
import java.util.*;
import java.util.List;

public class Main {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

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

    static final int N=405;
    static final int mod=1000000007;
    static final int INF=1000000009;
    static final int numBit=17;
    static FastReader r=new FastReader();
    static PrintWriter pw = new PrintWriter(System.out);

//    call dp[i][j] is number ways can turn on i computer but we just turn on j computer manually.
    static int [][]dp=new int[N][N];
    static int []p2=new int[N];
    static int []fac=new int[N];
    static int []ifac=new int[N];
    static int M;

    public static int mul(int a,int b){
        return (int)(1l*a*b%M);
    }

    public static int poww(int a,int b){
        int r=1;
        while(b>0){
            if(b%2==1) r=mul(r,a);
            a=mul(a,a);
            b>>=1;
        }
        return r;
    }

    public static int inv(int x){
        return poww(x,M-2);
    }

    public static int add(int a,int b){
        a+=b;
        if(a>=M) a-=M;
        return a;
    }

    public static int bino(int n,int k){
        return mul(fac[n],mul(ifac[n-k],ifac[k]));
    }

    public static void main(String[] args) throws IOException {
        int n=r.nextInt();
        M=r.nextInt();
        fac[0]=1;
        ifac[0]=1;
        p2[0]=1;
        for(int i=1;i<=n;++i){
            fac[i]=mul(fac[i-1],i);
            ifac[i]=inv(fac[i]);
            p2[i]=mul(p2[i-1],2);
        }
        int ans=0;
        dp[0][0]=1;
        for(int i=0;i<=n;++i){
            for(int k=0;k<=i;++k){
                for(int j=1;j<=n-i+1;++j){
                    dp[i+j+1][k+j]=add(dp[i+j+1][k+j],mul(dp[i][k],mul(p2[j-1],bino(j+k,j))));
                }
            }
        }
        for(int i=0;i<=n+1;++i){
            ans=add(ans,dp[n+1][i]);
        }
        pw.print(ans);
        pw.close();
    }
}


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

public class Practice {
	public static long mod = (long) Math.pow(10, 9) + 7;
	public static long[][] dp;

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

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);

		String[] s2 = br.readLine().split(" ");

		int n = (int) Long.parseLong(s2[0]);
		long m = Long.parseLong(s2[1]);
		dp = new long[n + 2][n + 2];
		long[] power = new long[n + 1];
		mod = m;
		long[][] choose = new long[n + 2][n + 2];
		getPow(power, n + 1);
		getChoose(choose, 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; k + i <= n; k++) {
				//	System.out.println((j + k) + " " + k + " - " + choose[j + k][k]);
					dp[i + k + 1][j
							+ k] = (dp[i + k + 1][j + k] + (((dp[i][j] * power[k - 1]) % mod) * choose[j + k][k]) % mod)
									% mod;
				}
			}
		}
		long ans = 0;
		for (int i = 0; i <= n; i++) {
			ans = (ans + dp[n + 1][i]) % mod;
		}
		pw.println(ans);
		pw.close();
	}

	private static void getChoose(long[][] choose, int up, int dow) {
		// TODO Auto-generated method stub
		for (int i = 1; i < up; i++) {
			for (int j = 1; j <= i; j++) {
				if (j == 1 && i == 1) {
					choose[i][j] = 1;
				} else if (j == 1) {
					choose[i][j] = i;
				} else {
					choose[i][j] = (choose[i - 1][j] + choose[i - 1][j - 1]) % mod;
				}
			}
		}
	}

	private static void getPow(long[] power, int l) {
		// TODO Auto-generated method stub
		for (int i = 0; i < l; i++) {
			if (i == 0) {
				power[i] = 1;
			} else {
				power[i] = (power[i-1] * 2) % mod;
			}
		}
	}

}

//private static long getGCD(long l, long m) {
//// TODO Auto-generated method stub
//
//long t1 = Math.min(l, m);
//long t2 = Math.max(l, m);
//while (true) {
//	long temp = t2 % t1;
//	if (temp == 0) {
//		return t1;
//	}
//	t2 = t1;
//	t1 = temp;
//}
//}


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

public class _G14 {
    public static void main(String[] args) {
        MyScanner sc = new MyScanner();
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
        int t = 1;
        while (t-- > 0) {
            int n = sc.nextInt();
            mod = sc.nextLong();
            long res = 0;
            initFac(n + 7);
            long [] tpow = new long[n + 7];
            long [][] combo = new long[n + 6][n + 6];
            for (int i = 0; i <= n; i++) {
                for (int j = 0; j <= i; j++) {
                    if (j == 0 || j == i)
                        combo[i][j] = 1;
                    else
                        combo[i][j] = (combo[i - 1][j - 1] + combo[i - 1][j]) % mod;
                }
            }
            tpow[0] = 1;
            for (int i = 1; i <= n + 6; i++) tpow[i] = (tpow[i - 1] * 2) % mod;
            // dp[i][auto]
            long [][] dp = new long[n + 1][n + 1];
            for (int i = 1; i <= n; i++) dp[i][0] = tpow[i - 1];
            for (int i = 3; i <= n; i++) {
                for (int auto = 1; auto <= n / 2; auto++) {
                    if (!check(i, auto)) continue;
                    long total = 0;
                    for (int j = i - 2; j >= 1; j--) {
                        if (!check(j, auto - 1)) break;
                        int len = i - j - 1;
                        long ways = tpow[len - 1];
                        int picked = j - (auto - 1);
                        long interleave = combo[len + picked][picked];
                        ways = (ways * interleave) % mod;
                        ways = (ways * dp[j][auto - 1]) % mod;
                        total = (total + ways) % mod;
                    }
                    dp[i][auto] = total;
                    if (i == n) res = (res + dp[i][auto]) % mod;
                }
            }
            res = (res + dp[n][0]) % mod;
            out.println(res);
        }
        out.close();
    }

    static boolean check(int n, int auto) {
        int rem = n - auto;
        int seg = auto + 1;
        return rem >= seg;
    }

    static long[] fac;
    static long mod;

    static void initFac(long n) {
        fac = new long[(int)n + 1];
        fac[0] = 1;
        for (int i = 1; i <= n; i++) {
            fac[i] = (fac[i - 1]  * i) % mod;
        }
    }

    static long nck(int n, int k) {
        if (n < k)
            return 0;
        long den = inv((int) (fac[k] * fac[n - k] % mod));
        return fac[n] * den % mod;
    }

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

    static long inv(long x) {
        return pow(x, mod - 2);
    }

    static void sort(int[] a) {
        ArrayList<Integer> q = new ArrayList<>();
        for (int i : a) q.add(i);
        Collections.sort(q);
        for (int i = 0; i < a.length; i++) a[i] = q.get(i);
    }

    static void sort(long[] a) {
        ArrayList<Long> q = new ArrayList<>();
        for (long i : a) q.add(i);
        Collections.sort(q);
        for (int i = 0; i < a.length; i++) a[i] = q.get(i);
    }

    //-----------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 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;
        }

    }

}