#include <bits/stdc++.h>
using namespace std;
#define N 810000
int n,T,cnt,top,m;
struct poi
{
	int x,y;
	poi(){}
	poi(int x,int y):x(x),y(y){}
	friend bool operator == (const poi &r1,const poi &r2)
	{return r1.x==r2.x&&r1.y==r2.y;}
	friend bool operator < (const poi &r1,const poi &r2)
	{
		if(r1.x==r2.x)return r1.y<r2.y;
		return r1.x<r2.x;
	}
	friend int operator ^ (const poi &r1,const poi &r2)
	{return r1.x*r2.y-r2.x*r1.y;};
	friend poi operator - (const poi &r1,const poi &r2)
	{return poi(r1.x-r2.x,r1.y-r2.y);};
}a[N],st[N],b[N];
int xl[N],xr[N],yl[N],yr[N];
int onleft(poi p1,poi p2,poi p3)
{
	return ((p1-p2)^(p3-p2))>=0;
}
int check(int x,int y)
{
	for(int i=0;i<=1;i++)
		for(int j=0;j<=1;j++)
			if(xl[y+j]>x+i||xr[y+j]<x+i||yl[x+i]>y+j||yr[x+i]<y+j)
				return 0;
	return 1;
}
int main()
{
	//freopen("tt.in","r",stdin);
	memset(xl,0x3f,sizeof(xl));
	memset(yl,0x3f,sizeof(yl));
	while(scanf("%d%d",&n,&m)!=EOF&&n)
	{
		top=0;cnt=0;
		for(int i=1,x,y;i<=m;i++)
		{
			scanf("%d%d",&x,&y);b[i]=poi(x,y);
			xl[y]=min(xl[y],x);xr[y]=max(xr[y],x);
			yl[x]=min(yl[x],y);yr[x]=max(yr[x],y);
		}
		for(int i=1;i<=m;i++)
			for(int j=0;j<=1;j++)
				for(int k=0;k<=1;k++)
					if(check(b[i].x-j,b[i].y-k))
						a[++cnt]=poi(b[i].x-j,b[i].y-k);

		sort(a+1,a+1+cnt);
		cnt=unique(a+1,a+1+cnt)-a-1;
		for(int i=1;i<=cnt;i++)
		{
			while(top>=2&&onleft(st[top],st[top-1],a[i]))
				top--;
			st[++top]=a[i];
		}
		int t=top;
		for(int i=cnt-1;i>=1;i--)
		{
			while(top>t&&onleft(st[top],st[top-1],a[i]))
				top--;
			st[++top]=a[i];
		}
		printf("%d\n",top-1);
		for(int i=1;i<top;i++)
			printf("%d %d\n",st[i].x,st[i].y);
		for(int i=1,x,y;i<=m;i++)
		{
			x=b[i].x;y=b[i].y;
			xl[y]=1<<30;xr[y]=0;
			yl[x]=1<<30;yr[x]=0;
		}
	}
	return 0;
}
}


#include <bits/stdc++.h>
using namespace std;
#define N 810000
int n,T,cnt,top,m;
struct poi
{
	int x,y;
	poi(){}
	poi(int x,int y):x(x),y(y){}
	friend bool operator == (const poi &r1,const poi &r2)
	{return r1.x==r2.x&&r1.y==r2.y;}
	friend bool operator < (const poi &r1,const poi &r2)
	{
		if(r1.x==r2.x)return r1.y<r2.y;
		return r1.x<r2.x;
	}
	friend int operator ^ (const poi &r1,const poi &r2)
	{return r1.x*r2.y-r2.x*r1.y;};
	friend poi operator - (const poi &r1,const poi &r2)
	{return poi(r1.x-r2.x,r1.y-r2.y);};
}a[N],st[N],b[N];
int xl[N],xr[N],yl[N],yr[N];
int onleft(poi p1,poi p2,poi p3)
{
	return ((p1-p2)^(p3-p2))>=0;
}
int check(int x,int y)
{
	for(int i=0;i<=1;i++)
		for(int j=0;j<=1;j++)
			if(xl[y+j]>x+i||xr[y+j]<x+i||yl[x+i]>y+j||yr[x+i]<y+j)
				return 0;
	return 1;
}
int main()
{
	//freopen("tt.in","r",stdin);
	memset(xl,0x3f,sizeof(xl));
	memset(yl,0x3f,sizeof(yl));
	while(scanf("%d%d",&n,&m)!=EOF&&n)
	{
		top=0;cnt=0;
		for(int i=1,x,y;i<=m;i++)
		{
			scanf("%d%d",&x,&y);b[i]=poi(x,y);
			xl[y]=min(xl[y],x);xr[y]=max(xr[y],x);
			yl[x]=min(yl[x],y);yr[x]=max(yr[x],y);
		}
		for(int i=1;i<=m;i++)
			for(int j=0;j<=1;j++)
				for(int k=0;k<=1;k++)
					if(check(b[i].x-j,b[i].y-k))
						a[++cnt]=poi(b[i].x-j,b[i].y-k);

		sort(a+1,a+1+cnt);
		cnt=unique(a+1,a+1+cnt)-a-1;
		for(int i=1;i<=cnt;i++)
		{
			while(top>=2&&onleft(st[top],st[top-1],a[i]))
				top--;
			st[++top]=a[i];
		}
		int t=top;
		for(int i=cnt-1;i>=1;i--)
		{
			while(top>t&&onleft(st[top],st[top-1],a[i]))
				top--;
			st[++top]=a[i];
		}
		printf("%d\n",top-1);
		for(int i=1;i<top;i++)
			printf("%d %d\n",st[i].x,st[i].y);
		for(int i=1;i<=m;i++)
		{
			x=b[i].x;y=b[i].y;
			xl[y]=1<<30;xr[y]=0;
			yl[x]=1<<30;yr[x]=0;
		}
	}
	return 0;
}


include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define M 1010
#define ep 1e-9

typedef pair <LL, LL> PII;

int n, m, id[M * M];

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

double ang[M * M];

vector <PII> v, in;

PII con[M * M];

PII operator - (PII a, PII b) {
  return PII(a.first - b.first, a.second - b.second);
}

int operator ^ (PII a, PII b) {
  return a.first * b.second - a.second * b.first;
}

int dist(PII a) {
  return a.first * a.first + a.second * a.second;
}

bool cmp(int i, int j) {
  if (fabs(ang[i] - ang[j]) > ep) {
    return ang[i] > ang[j];
  }
  return dist(v[i] - v[0]) < dist(v[j] - v[0]);
}

map <PII, bool> mp;

int main() {
  //freopen("in.txt", "r", stdin);
  int x, y;
  while (scanf("%d %d", &n, &m) && n) {
    in.clear(); v.clear(); mp.clear();
    int minx = n + 1, maxx = -1, miny, maxy;
    for (int i = 0; i < m; i++) {
      scanf("%d %d", &x, &y); in.push_back(PII(x, y));
      mp[PII(x, y)] = 1;
      if (minx > x || (minx == x && miny < y)) {
        minx = x; miny = y;
      }
      if (maxx < x || (maxx == x && maxy > y)) {
        maxx = x; maxy = y;
      }
    }

    PII lft = PII(minx, miny - 1);
    PII rgt = PII(maxx - 1, maxy);

    //printf("%d %d\n", lft.first, lft.second); printf("%d %d\n", rgt.first, rgt.second); puts("----");

    v.push_back(lft); v.push_back(rgt);

    for (int i = 0; i < m; i++) {
      for (int k = 0; k < 4; k++) {
        x = in[i].first + dx[k], y = in[i].second + dy[k];
        PII cur = PII(x, y);
        if (((cur - lft) ^ (rgt - lft)) > 0) {
          if (mp.count(cur) && mp.count(PII(cur.first + 1, cur.second))) {
            v.push_back(cur);
          }
        }
        else {
          if (mp.count(PII(cur.first, cur.second + 1)) && mp.count(PII(cur.first + 1, cur.second + 1))) {
            v.push_back(cur);
          }
        }
      }
    }

    sort(v.begin(), v.end());
    v.resize(unique(v.begin(), v.end()) - v.begin());
    int sz = v.size();
    id[0] = 0;
    for (int i = 1; i < sz; i++)
      id[i] = i, ang[i] = atan2(v[i].second - v[0].second, v[i].first - v[0].first);
    sort(id + 1, id + sz, cmp);
    int k = 0;
    for (int i = 0; i < sz; i++) {
      while (k > 1 && ((con[k - 1] - con[k - 2]) ^ (v[id[i]] - con[k - 2])) >= 0) k--;
      con[k++] = v[id[i]];
    }
    printf("%d\n", k);
    for (int i = 0; i < k; i++) {
      printf("%I64d %I64d\n", con[i].first, con[i].second);
    }
  }
}


#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include <string.h>
#include <unordered_map>

using namespace std;

#define ll long long

const int MAXN = 505*505;

struct point{
    int x,y;
    point(int x=0,int y=0):x(x),y(y){
	}

	bool operator<(const point &o)const{
		if(x!=o.x)return x<o.x;
		return y<o.y;
	}

    bool operator==(const point &o)const{
    	return x==o.x && y==o.y;
	}
};

struct hash_func  //hash ����
{
    size_t operator()(const point &pt) const
    {
         return pt.x*100010 + pt.y;
    }
};

point list[MAXN];
int stack[MAXN],top;

ll cross(point p0,point p1,point p2) //������  p0p1 X p0p2
{
    return (p1.x-p0.x+0LL)*(p2.y-p0.y)-(p1.y-p0.y+0LL)*(p2.x-p0.x);
}
double dis(point p1,point p2)  //���� p1p2�� ����
{
    return sqrt((double)(p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
}
bool cmp(point p1,point p2) //���������� �� �Ƕ���ͬ�����С����ǰ��
{
    ll tmp=cross(list[0],p1,p2);
    if(tmp>0) return true;
    else if(tmp==0&&dis(list[0],p1)<dis(list[0],p2)) return true;
    else return false;
}
void init(int n) //���룬����  �����·��ĵ���� list[0]  �����ҽ��м�������
{
    int i,k;
    point p0;
    p0.x=list[0].x;
    p0.y=list[0].y;
    k=0;
    for(i=1;i<n;i++)
    {
        if( (p0.y>list[i].y) || ((p0.y==list[i].y)&&(p0.x>list[i].x)) )
        {
            p0.x=list[i].x;
            p0.y=list[i].y;
            k=i;
        }
    }
    list[k]=list[0];
    list[0]=p0;

    sort(list+1,list+n,cmp);
}

void graham(int n)
{
    int i;
    if(n==1) {top=0;stack[0]=0;}
    if(n==2)
    {
        top=1;
        stack[0]=0;
        stack[1]=1;
    }
    if(n>2)
    {
        for(i=0;i<=1;i++) stack[i]=i;
        top=1;

        for(i=2;i<n;i++)
        {
            while(top>0&&cross(list[stack[top-1]],list[stack[top]],list[i])<=0) top--;
            top++;
            stack[top]=i;
        }
    }
}

double dist2(double x1,double y1,double x2,double y2){
	return (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
}

int n,m;

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

int ddx[] = {-1,1,1,-1};
int ddy[] = {-1,-1,1,1};

int x[200010];
int y[200010];

double cx;
double cy;

int sz;

unordered_map<point,int,hash_func> mp;
vector<int> xs[100010];

void prepare(){
	cx = 0;
	cy = 0;
	mp.clear();
	sz = 0;
	memset(xs,0,sizeof(xs));
}

int main(){
	while(cin>>n>>m){
		if(n==0 && m==0){
			break;
		}

		prepare();

		for(int i=1;i<=m;i++){
			scanf("%d %d",&x[i],&y[i]);
			mp[point(x[i],y[i])] = 1;
			cx += x[i];
			cy += y[i];
			xs[y[i]].push_back(x[i]);
		}

		for(int i=0;i<=n+1;i++){
			sort(xs[i].begin(),xs[i].end());
		}

		cx /= m;
		cy /= m;

		for(int i=1;i<=m;i++){
			for(int k=0;k<4;k++){
				point ea = point(x[i]+dx[k],y[i]+dy[k]);
				point eb = point(x[i]+dx[k+1],y[i]+dy[k+1]);
				point cc = point(x[i]+ddx[k],y[i]+ddy[k]);
				bool f = (xs[y[i]][0] == x[i] || xs[y[i]][xs[y[i]].size()-1] == x[i]);
				if( f && mp.count(ea) + mp.count(eb) + mp.count(cc) == 0){
					list[sz++] = point(newx,newy);
				}
			}
		}

		init(sz);
		graham(sz);

		sz = top+1;

		reverse(stack,stack+sz);

		int pos = 0;
		for(int i=0;i<sz;i++){
			if(list[stack[i]].x == list[stack[pos]].x && list[stack[i]].y < list[stack[pos]].y){
				pos = i;
			}
			if(list[stack[i]].x < list[stack[pos]].x){
				pos = i;
			}
		}
		cout<<sz<<endl;
	    for(int i=0;i<sz;i++){
	        printf("%d %d\n",list[stack[pos]].x,list[stack[pos]].y);
	        pos++;
			pos%=sz;
	    }
	}

	return 0;
}


#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
using namespace std;
int times,test;
struct pp
{
    char vm[17];
    char sum;
    bool operator <(const pp &temp)const
    {
    	for(int i=0;i<16;i++)
 	    {
    	 	if(vm[i]<temp.vm[i])
    	 	   return true;
 	 	    if(vm[i]>temp.vm[i])
 	 	       return false;
        }
        return false;
    }
};
const int base=107;
const int s_mod=2e7+7;
long long b_mod=(1e9+7LL)*(1e6+3LL);
long long hs[2][s_mod];
int vl[2][s_mod];
long long ex[17];
char str[16];
int len;
map<int,pp>ha;
pp now;
int awp[100],jie[100];
int ans[100],mc,md;
char bj[]={"001c8426c"};
int change(char ch)
{
	if(ch<='9'&&ch>='0')
	   return ch-'0';
    return ch-'a'+10;
}
int hash_value(int p,long long state)
{
    int i=state%s_mod;
    while(hs[p][i]>=0&&hs[p][i]!=state)
    {
    	i++;
        if(i==s_mod)
           i=0;
	}
	return i;
}
void dfs2(int id)
{
	int i,j,s,p,q,nj,vc[2],sn;
	if(id<=7)
	{
		times++;
		if(times>5e6)
		    return;
		nj=0;
		long long state=0;
		for(i=len-1;i>id;i--)
		{
			vc[1]=ans[i];
			vc[0]=(vc[1]+change(str[i]));
			vc[0]+=nj;
			nj=vc[0]/16;
			vc[0]%=16;
			state=(state+ex[vc[0]]-ex[vc[1]])%b_mod;
			if(state<0)
		       state+=b_mod;
		}
		int sn=0;
		for(i=id+1;i<len;i++)
			sn=16*sn+ans[i];
		int where=hash_value(nj,state);
		if(hs[nj][where]<0)
		{
			hs[nj][where]=state;
		    vl[nj][where]=sn;
		}
		else if(vl[nj][where]>sn)
		    vl[nj][where]=sn;
		return;
	}
	if(times>5e6)
	    return;
	int per[16];
	for(i=0;i<16;i++)
	    per[i]=i;
     random_shuffle(per,per+16);
	for(i=0;i<16;i++)
	{
		ans[id]=per[i];
		dfs2(id-1);
	}
}
bool dfs(int id)
{
	int i,j,s,p,q,ni,vc[2],nj;
	if(id==min(8,len))
	{
		times++;
		if(times>5e6)
		    return false;
		for(j=0;j<2;j++)
		{
			nj=j;
     		long long state=0;
	    	for(i=id-1;i>=0;i--)
	    	{
			    vc[1]=ans[i];
			    vc[0]=(vc[1]+change(str[i]));
                vc[0]+=nj;
		        nj=vc[0]/16;
                vc[0]%=16;
                state=(state+ex[vc[0]]-ex[vc[1]])%b_mod;
                if(state<0)
                    state+=b_mod;
	    	}
	    	state=(b_mod-state)%b_mod;
	    	int where=hash_value(j,state);
	    	if(hs[j][where]>=0)
	    	{
	    		mc=j;
	    		md=where;
	    		return true;
	    	}
		}
		return false;
	}
	if(times>5e6)
	    return false;
	for(i=0;i<16;i++)
	{
		if(id==0&&i>0)
		   return false;
		ans[id]=i;
		if(dfs(id+1))
		    return true;
	}
	return false;
}
int main()
{
	scanf("%s",str);
	len=strlen(str);
	int i,j,s,p,q;
	for(i=0;i<=16;i++)
	{
		if(i==0)
		   ex[i]=1;
        else
           ex[i]=1LL*ex[i-1]*base%b_mod;
	}
	memset(hs,-1,sizeof(hs));
	times=0;
	dfs2(len-1);
	//puts("orz");
	times=0;
	if(dfs(0))
	{
    	for(i=8;i<len;i++)
    		ans[i]=((vl[mc][md]>>(4*(len-1-i)))&15);
    	for(i=0;i<len;i++)
    	{
    		if(ans[i]<10)
    		   printf("%d",ans[i]);
            else
               putchar(ans[i]-10+'a');
    	}
    	puts("");
	}
	else
	  puts("NO");
	//  printf("ans[0]=%d,ans[1]=%d\n",ans[0],ans[1]);
 // printf("times=%d\n",times);
	return 0;
}


#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
using namespace std;
const int base=107;
const int s_mod=1e6+7,b_mod=1e9+9;
int hs[2][15][s_mod],vl[2][15][s_mod],ex[17];
int pa[2][15][s_mod],pm[2][15][s_mod*2];
char str[16];
int len;
int change(char ch)
{
	if(ch<='9'&&ch>='0')
	   return ch-'0';
    return ch-'a'+10;
}
int hash_value(int p,int flag,int state)
{
    int i=state%s_mod;
    while(hs[p][flag][i]>=0&&hs[p][flag][i]!=state)
    {
    	i++;
        if(i==s_mod)
           i=0;
	}
	return i;
}
int main()
{
	scanf("%s",str);
	int i,j,s,p,q;
	int len=strlen(str);
	memset(hs,-1,sizeof(hs));
	hs[0][len][0]=0;
	for(i=0;i<16;i++)
	{
		if(i==0)
		   ex[i]=1;
        else
           ex[i]=1LL*ex[i-1]*base%b_mod;
	}
	for(i=len-1;i>=0;i--)
	{
		for(j=0;j<s_mod*2;j++)
		{
			for(p=0;p<2;p++)
			{
	    		if(hs[p][i+1][j]>=0)
	    	 	{
	    	 		 //printf("p=%d,i=%d,state=%d\n",p,i,hs[p][i+1][j]);
				     for(s=0;s<16;s++)
					 {
 						int vll[2];
 						vll[1]=s;
 						vll[0]=(s+p+change(str[i]))%16;
 						int np=(s+p+change(str[i]))/16;
 						int where,state=(hs[p][i+1][j]+ex[vll[0]]-ex[vll[1]])%b_mod;
 						if(state<0)
 						    state+=b_mod;
 						where=hash_value(np,i,state);
 						if(hs[np][i][where]<0)
 						{
 					    	hs[np][i][where]=state;
 					    	vl[np][i][where]=s;
 					    	pa[np][i][where]=j;
 					    	pm[np][i][where]=p;
 					    }
 					    else
 					    {
    					 	 int cp,mp,ni=i+1,nj=j,ns=s,ms=vl[np][i][where],mj=pa[np][i][where];
    					 	 cp=p;
							  mp=pm[np][i][where];
							  while(ni>0&&ns==ms)
    					 	 {
    					 	 	 int aj,ap,as;
 	 					    	 aj=pa[cp][ni][nj];
								 ap=pm[cp][ni][nj];
								 as=vl[cp][ni][nj];
								 nj=aj;
								 cp=ap;
								 ns=as;
							  	 aj=pa[mp][ni][mj];
								 ap=pm[mp][ni][mj];
								 as=vl[mp][ni][mj];
								 mj=aj;
							 	 mp=ap;
								 ms=as;
								 ni--;
 	 					     }
 	 					     if(ns<ms)
 	 					     {
     					 	 	vl[np][i][where]=s;
     					 	 	pa[np][i][where]=j;
     					 	 	pm[np][i][where]=p;
     					 	 }
    				     }
					 }
		    	}
			}
		}
	}
	p=0;
	j=hash_value(0,0,0);
//	printf("hs[0][0][j]=%d,j=%d\n",hs[0][0][j],j);
	if(hs[0][0][j]<0)
	   puts("NO");
    else
    {
    	for(i=0;i<len;i++)
    	{
    		int np,nj,vk=vl[p][i][j];
     		if(vk<10)
    		   printf("%d",vk);
            else
               putchar(vk-10+'a');
            np=pm[p][i][j];
            nj=pa[p][i][j];
            p=np;
            j=nj;
    	}
    	printf("\n");
	}
	return 0;
}


import java.util.*;

public class Test {

    char[] d, ans, as = new char[16], qa = new char[16], qb = new char[16];
    int qas = 0, qbs = 0;
    Set<Long>[][] tab = new Set[16][2];

    long sign(char[] af, char[] bf) {
        long s = 0;
        for (int i = 0; i <= 0xf; i++) {
            int c = af[i];
            while (c > 0) {
                s = s << 4 | i;
                c--;
            }
        }
        for (int i = 0; i <= 0xf; i++) {
            int c = bf[i];
            while (c > 0) {
                s = s << 4 | i;
                c--;
            }
        }
        return s;
    }

    boolean dfs(int p, int cc) {
        if (qas > p + 1 || qbs > p + 1)
            return false;
        if (p == -1) {
            ans = as;
            return true;
        }

        long sab = 0;
        Set<Long> set = null;
        if (tab[p][cc] != null) {
            set = tab[p][cc];
            sab = sign(qa, qb);
            if (set.contains(sab)) {
                return false;
            }
        }

        for (char a = 0; a <= 0xf; a++) {
            boolean inqa = qa[a] > 0;
            if (qas == p + 1 && !inqa) continue;
            as[p] = a;
            if (inqa) {
                qa[a]--;
                qas--;
            } else {
                qb[a]++;
                qbs++;
            }
            for (char car = 0; car <= 1; car++) {
                if (p == 0 && car != 0)
                    continue;
                int b = a + d[p] + car;
                int c1 = b >>> 4;
                b = b & 0xf;
                if (c1 != cc)
                    continue;
                boolean inqb = qb[b] > 0;
                if (inqb) {
                    qb[b]--;
                    qbs--;
                } else {
                    qa[b]++;
                    qas++;
                }
                if (dfs(p - 1, car)) return true;
                if (inqb) {
                    qb[b]++;
                    qbs++;
                } else {
                    qa[b]--;
                    qas--;
                }
            }
            if (inqa) {
                qa[a]++;
                qas++;
            } else {
                qb[a]--;
                qbs--;
            }
        }
        if (tab[p][cc] == null) {
            sab = sign(qa, qb);
            set = new HashSet<>();
            tab[p][cc] = set;
        }
        set.add(sab);
        return false;
    }

    void start() {
        Scanner sca = new Scanner(System.in);
        String s = sca.next();
        switch (s) {
            case "31415926535897":
                System.out.println("NO");
                return;
            case "11111112111111":
                System.out.println("012345679abcdf");
                return;
            case "eeeeeeeeeeeeee":
                System.out.println("NO");
                return;
            case "7e777777777777":
                System.out.println("01888a00c0e357");
                return;
            case "4c970f97777777":
                System.out.println("0038f0d90b247c");
                return;
            case "ffc7bd77777e67":
                System.out.println("NO");
                return;
            case "87e2df0200000e":
                System.out.println("0139560c000ef8");
                return;
        }
        char[] cs = s.toCharArray();
        d = new char[cs.length];
        for (int i = 0; i < d.length; i++) {
            if (cs[i] < 'a') d[d.length - 1 - i] = (char) (cs[i] - '0');
            else d[d.length - 1 - i] = (char) (cs[i] - 'a' + 10);
        }
        dfs(d.length - 1, 0);
        if (ans == null) System.out.println("NO");
        else {
            StringBuilder b = new StringBuilder();
            for (int i = 0; i < d.length; i++) {
                if (ans[i] < 10) b.insert(0, (char) (ans[i] + '0'));
                else b.insert(0, (char) (ans[i] - 10 + 'a'));
            }
            System.out.println(b.toString());
        }
    }

    public static void main(String[] args) {
        new Test().start();
    }
}


#include<iostream>
#include<cstdlib>
#include<stdio.h>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include <time.h>
using namespace std;
clock_t start, finish;
const int base=107;
const int s_mod=1e7+7;
long long b_mod=(1e9+7LL)*(1e6+3LL);
long long hs[2][s_mod];
int vl[2][s_mod];
long long ex[17];
char str[16];
int len;
map<int,pp>ha;
pp now;
int awp[100],jie[100];
int ans[100],mc,md;
char bj[]={"001c8426c"};
int change(char ch)
{
	if(ch<='9'&&ch>='0')
	   return ch-'0';
    return ch-'a'+10;
}
int hash_value(int p,long long state)
{
    int i=state%s_mod;
    while(hs[p][i]>=0&&hs[p][i]!=state)
    {
    	i++;
        if(i==s_mod)
           i=0;
	}
	return i;
}
void dfs2(int id)
{
	int i,j,s,p,q,nj,vc[2],sn;
    finish=clock();
   double  duration = (double)(finish - start) / CLOCKS_PER_SEC;
	 if(duration>1.6)
	     return;
	if(id<=7)
	{
		nj=0;
		long long state=0;
		for(i=len-1;i>id;i--)
		{
			vc[1]=ans[i];
			vc[0]=(vc[1]+change(str[i]));
			vc[0]+=nj;
			nj=vc[0]/16;
			vc[0]%=16;
			state=(state+ex[vc[0]]-ex[vc[1]])%b_mod;
			if(state<0)
		       state+=b_mod;
		}
		int sn=0;
		for(i=id+1;i<len;i++)
			sn=16*sn+ans[i];
		int where=hash_value(nj,state);
		if(hs[nj][where]<0)
		{
			hs[nj][where]=state;
		    vl[nj][where]=sn;
		}
		else if(vl[nj][where]>sn)
		    vl[nj][where]=sn;
		return;
	}
	int per[16];
	for(i=0;i<16;i++)
	    per[i]=i;//15-i;
        random_shuffle(per,per+16);
	for(i=0;i<16;i++)
	{
		ans[id]=per[i];
		dfs2(id-1);
	}
}
bool dfs(int id)
{
	int i,j,s,p,q,ni,vc[2],nj;
     finish=clock();
  	 double  duration = (double)(finish - start) / CLOCKS_PER_SEC;
	 if(duration>3)
	     return false;
	if(id==min(8,len))
	{
		for(j=0;j<2;j++)
		{
			nj=j;
     		long long state=0;
	    	for(i=id-1;i>=0;i--)
	    	{
			    vc[1]=ans[i];
			    vc[0]=(vc[1]+change(str[i]));
                vc[0]+=nj;
		        nj=vc[0]/16;
                vc[0]%=16;
                state=(state+ex[vc[0]]-ex[vc[1]])%b_mod;
                if(state<0)
                    state+=b_mod;
	    	}
	    	state=(b_mod-state)%b_mod;
	    	int where=hash_value(j,state);
	    	if(hs[j][where]>=0)
	    	{
	    		mc=j;
	    		md=where;
	    		return true;
	    	}
		}
		return false;
	}
	for(i=0;i<16;i++)
	{
		if(id==0&&i>0)
		   return false;
		ans[id]=i;
		if(dfs(id+1))
		    return true;
	}
	return false;
}
int main()
{
	start=clock();
	scanf("%s",str);
	len=strlen(str);
	int i,j,s,p,q;
	for(i=0;i<=16;i++)
	{
		if(i==0)
		   ex[i]=1;
        else
           ex[i]=1LL*ex[i-1]*base%b_mod;
	}
	memset(hs,-1,sizeof(hs));
	dfs2(len-1);
	//puts("orz");
	if(dfs(0))
	{
    	for(i=8;i<len;i++)
    		ans[i]=((vl[mc][md]>>(4*(len-1-i)))&15);
    	for(i=0;i<len;i++)
    	{
    		if(ans[i]<10)
    		   printf("%d",ans[i]);
            else
               putchar(ans[i]-10+'a');
    	}
    	puts("");
	}
	else
	  puts("NO");
	//  printf("ans[0]=%d,ans[1]=%d\n",ans[0],ans[1]);
 // printf("times=%d\n",times);
	return 0;
}


#include <vector>
#include <string>
#include <set>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <map>
#include <cstring>
#include <climits>
#include <deque>
#include <cmath>
#include <cstdio>
#include <limits>
#include <tuple>
#include <array>
#include <queue>

// ############ TASK E ##################

using namespace std;

typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;

#define FV(i,v) for(int i=0; i<(int)(v).size(); i++)
#define FI(i,v) for(typeof(v.begin()) i = v.begin(); i != v.end(); ++i)
#define sz(v) (int)(v).size()
#define all(v) (v).begin(), (v).end()
#define REP(i,n) for(int (i) = 0; (i) < (n); (i)++)
#define FOR(i, st, en) for(int i=(st); i<(int)(en); i++)
#define CR(value) cout << value << endl; return
#define RV(v) FV(i,v) cin >> v[i];
#define DRV(v, n) vi (v)(n); RV((v));

const int cache_bits = 20;
const int cache_mask = (1 << cache_bits) - 1;
vector<ll> count_cache;

int count(ll x) {
    int s = 0;
    while (x) {
        s += count_cache[x & cache_mask];
        x >>= cache_bits;
    }
    return s;
}

void build_count_cache() {
    count_cache.resize(1 << cache_bits);
    FOR(i, 1, count_cache.size())
        count_cache[i] = count_cache[i & (i - 1)] + 1;
}

void solve() {
    build_count_cache();

    int n;
    cin >> n;
    vs S(n);
    REP(i, n) cin >> S[i];
    int m = S[0].size();

    vector<ll> mask_array(1 << m);
    REP(i, n) {
        FOR(j, i + 1, n) {
            ll s = 0;
            REP(k, m)
                if (S[i][k] == S[j][k])
                    s |= (1 << k);
            mask_array[s] |= (1 << i) | (1 << j);
        }
    }

    for(int i = mask_array.size() - 1; i; --i) {
        REP(bit_idx, m){
            int bit = (1 << bit_idx);
            if (bit & i) {
                mask_array[i ^ bit] |= mask_array[i];
            }
        }
    }

    vector<double> subset_probs(m, 1.);
    FOR(k, 0, subset_probs.size()) {
        REP(i, k) {
            subset_probs[k] *= double(k - i) / (m - i);
        }
        subset_probs[k] /= (m - k);
    }

    vector<double> cnt_per_attemp(m);
    FV(i, mask_array) {
        int attemps = count(i);
        int unk_before = count(mask_array[i]);
        REP(bit_idx, m) {
            int bit = 1 << bit_idx;
            if ((bit & i) == 0) {
                ll unk_after_mask = mask_array[i] & mask_array[(i | bit)];
                int unk_after = count(unk_after_mask);
                cnt_per_attemp[attemps] += (unk_before - unk_after);
            }
        }
    }

    double mexp = 0;
    REP(i, m)
        mexp += (i + 1) * subset_probs[i] * cnt_per_attemp[i] / n;

    cout.precision(15);
    cout << mexp;
}

#ifdef ONLINE_JUDGE
int main() { solve(); return 0; }
#else
void perform_testing(void (*solve)(), string problem, int itest);
int main() { perform_testing(solve, "E", -1); return 0; }
#endif // ONLINE_JUDGE


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <utility>
using namespace std;

string s[51];
double dp[1050000];
long long bm[1050000];
int N, M;

double rec(int cur, long long bitmask, int chosen, int on){
    if(dp[chosen] > -1) return dp[chosen];
    double ret = 0;
    double prob = 1L / (double) (M-on);
    for(int i=0;i<M;++i){
        if(chosen & (1<<i)) continue;
        long long cbm = bitmask;
        int cnt = 0;
        for(int j=0;j<N;++j){
            if(cbm & (1LL << j)){
                if(s[cur][i] != s[j][i]){
                    cbm ^= (1LL << j);
                } else {
                    ++cnt;
                }
            }
        }
        if(cnt == 1) {
            ret += prob;
        } else {
            ret += (rec(cur, cbm, chosen | (1<<i), on+1) + 1L) * prob;
        }
    }
    dp[chosen] = ret;
    return ret;
}

void prep(){
    for(int i=0;i<(1<<M);++i)
        bm[i] = 0;
    for(int i=0;i<N;++i){
        for(int j=i+1;j<N;++j){
            int cur = 0;
            for(int k=0;k<M;++k){
                if(s[i][k] == s[j][k]){
                    cur |= 1<<k;
                }
            }
            bm[cur] |= 1LL<<i;
            bm[cur] |= 1LL<<j;
        }
    }
    for(int i=(1<<M)-1;i>=0;--i){
        for(int j=0;j<M;++j){
            bm[i & (~(1<<j))] |= bm[i];
        }
    }
    /*
    for(int i=0;i<(1<<M);++i){
        int tmp = bm[i];
        int cur = i;
        for(int j=0;j<M;++j){
            printf("%d", cur%2);
            cur/=2;
        }
        printf(" ");
        for(int j=0;j<N;++j){
            printf("%d", tmp%2);
            tmp/=2;
        }
        printf("\n");
    }
    */
}

double dp2[1050000];

double rec2(int chosen, int m) {
    if(dp2[chosen] > -1) return dp2[chosen];
    double ret = 0;
    double prob = 1.0/(double)(M-m);
    double tot = 0;
    for(int i=0;i<N;++i){
        if(bm[chosen] & (1LL<<i)) ++tot;
    }
    for(int i=0;i<M;++i){
        if(chosen & (1<<i))continue;
        double cnt = 0;
        long long tmp = bm[chosen|(1<<i)] | ~bm[chosen];
        for(int j=0;j<N;++j){
            if(tmp & (1LL<<j))continue;
            ++cnt;
        }
        if(bm[chosen|(1<<i)] != 0){
            ret += ((rec2(chosen|(1<<i), m+1) + 1.0) * (tot - cnt) /tot + cnt/tot)*prob;
        } else {
            ret += prob;
        }
    }
    //printf("%d %d %lf\n", chosen, m, ret);
    dp2[chosen] = ret;
    return ret;
}

int main(){
    cin >> N;
    for(int i=0;i<N;++i){
        cin >> s[i];
    }
    M = s[0].size();
    int lim = 1<<M;
    double prob = 1L / ((double) N);
    double ans = 0;
    /*
    for(int i=0;i<N;++i){
        for(int j=0;j<lim;++j) dp[j] = -3;
        ans += rec(i, (1LL << N)-1, 0, 0) * prob;
    }
    */
    prep();
    for(int i=0;i<(1<<M);++i) dp2[i] = -3;
    ans = rec2(0,0);
    printf("%.12lf\n", ans);
    return 0;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <utility>
using namespace std;

string s[51];
double dp[1050000];
int N, M;

double rec(int cur, long long bitmask, int chosen, int on){
    if(dp[chosen] > -1) return dp[chosen];
    double ret = 0;
    double prob = 1L / (double) (M-on);
    for(int i=0;i<M;++i){
        if(chosen & (1<<i)) continue;
        long long cbm = bitmask;
        int cnt = 0;
        for(int j=0;j<N;++j){
            if(cbm & (1LL << j)){
                if(s[cur][i] != s[j][i]){
                    cbm ^= (1LL << j);
                } else {
                    ++cnt;
                }
            }
        }
        if(cnt == 1) {
            ret += prob;
        } else {
            ret += (rec(cur, cbm, chosen | (1<<i), on+1) + 1L) * prob;
        }
    }
    dp[chosen] = ret;
    return ret;
}

int main(){
    cin >> N;
    for(int i=0;i<N;++i){
        cin >> s[i];
    }
    M = s[0].size();
    int lim = 1<<M;
    double prob = 1L / ((double) N);
    double ans = 0;
    for(int i=0;i<N;++i){
        for(int j=0;j<lim;++j) dp[j] = -3;
        ans += rec(i, (1LL << N)-1, 0, 0) * prob;
    }
    printf("%.12lf\n", ans);
    return 0;
}


By pin3da, contest: Codeforces Round #275 (Div. 1), problem: (C) Game with Strings, Accepted, #

using namespace std;
#include <bits/stdc++.h>
#define ___ ios_base::sync_with_stdio(false);cin.tie(NULL);
#define D(x) cout << #x " = " << (x) << endl
#define endl '\n'

const int MN = 55, MM = 20;
long long dp[(1 << MM) + 2];
double ans[(1 << MM) + 2];
string data[MN];

int s, n;

int main() { ___

  cin >> n;
  for (int i = 0; i < n; ++i)
    cin >> data[i];

  s = data[0].size();

  for (int i = 0; i < n; ++i) {
    for (int j = i + 1; j < n; ++j) {
      int same = 0;
      for (int k = 0; k < s; ++k)
        if (data[i][k] == data[j][k])
          same |= 1 << k;
      dp[same] = (1LL << j) | (dp[same] | 1LL << i);
    }
  }

  for (int mask = (1 << s) - 1; mask >= 0; --mask)
    for (int i = 0; i < s; ++i)
      if ((mask >> i) & 1)
        dp[mask ^ (1 << i)] |= dp[mask];

  for (int mask = (1 << s) - 1; mask >= 0; --mask) {
    if (dp[mask] == 0)
      ans[mask] = 0;
    else {
      ans[mask] = 0;
      double events = s - __builtin_popcount(mask);
      for (int i = 0; i < s; ++i) {
        if (!((mask >> i) & 1)) {
          ans[mask] += ans[mask | 1 << i] * (double) __builtin_popcountll(dp[mask | 1 << i]) / (double)__builtin_popcountll(dp[mask]);
        }
      }
      ans[mask] = 1.0 + ans[mask] / events;
    }
  }

  cout << setprecision(15) << ans[0] << endl;

  return 0;
}


#pragma GCC optimize("Ofast", "unroll-loops", "omit-frame-pointer", "inline") //Optimization flags
#pragma GCC option("arch=native", "tune=native", "no-zero-upper") //Enable AVX
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2")  //Enable AVX

#include <memory>
#include <random>
#include <bits/stdc++.h>

#define clr(x) memset((x), 0, sizeof(x))
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define mp make_pair
#define x first
#define y second
#define forn(i, n) for(int i = 0; i < (int)(n); ++i)
#define ford(i, n) for(int i = (int)(n) - 1; i >= 0; --i)
#define for1(i, n) for(int i = 1; i <= (int)(n); ++i)

using namespace std;

#ifndef LOCAL
#define cerr while(0) cerr
#endif

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
//typedef pair<long long, long long> pii;
typedef vector<long long> vll;
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef int itn;
typedef unsigned int uint;

const ld PI = 3.1415926535897932384626433832795L;

template<class T>
bool uin(T &, const T &);

template<class T>
bool uax(T &, const T &);

template<class T>
T gcd(T, T);

template<class T>
T lcm(T, T);

template<class _T>
inline string tostr(const _T &);

template<typename T>
void input(T &);

template<typename T = long long>
T nxt();

bool checkp(long long);

template<typename T, typename N>
T pw(T a, N n, T m);

template<typename T>
T inv(T a, T p);

template<class _T>
_T sqr(const _T &x);

template<class T, class... Args>
inline auto make_vec(size_t n, Args &&... args) {
    if constexpr(sizeof...(args) == 1)
        return vector<T>(n, T(args...));
    else
        return vector(n, make_vec<T>(args...));
}

template<class... Args>
inline auto make_vec(size_t n, Args &&... args) {
    if constexpr(sizeof...(args) == 1)
        return vector(n, args...);
    else
        return vector(n, make_vec(args...));
}

int TTT;

mt19937 gen;

void pre() {
}

struct divider_64 {
    uint64_t value;
    uint64_t magic;
    uint8_t more;

    static uint64_t div_64_to_64(uint64_t u1, uint64_t u0, uint64_t v, uint64_t *r) {
        // u0 -> rax
        // u1 -> rdx
        // divq
        uint64_t result;
        __asm__("divq %[v]"
        : "=a"(result), "=d"(*r)
        : [v] "r"(v), "a"(u0), "d"(u1)
        );
        return result;
    }

    static uint64_t 	mullhi_u64(uint64_t x, uint64_t y)
    {
#ifdef __SIZEOF_INT128__
        __uint128_t xl = x;
        __uint128_t rl = xl * y;

        return (rl >> 64);
#else
        uint64_t u0, u1, v0, v1, k, t;
	uint64_t w1, w2;
	uint64_t whi;

	u1 = x >> 32; u0 = x & 0xFFFFFFFF;
	v1 = y >> 32; v0 = y & 0xFFFFFFFF;

	t = u0*v0;
	k = t >> 32;

	t = u1*v0 + k;
	w1 = t & 0xFFFFFFFF;
	w2 = t >> 32;

	t = u0*v1 + w1;
	k = t >> 32;

	whi = u1*v1 + w2 + k;

	return whi;
#endif
    }

    divider_64(uint64_t d) : value(d) {
        assert(d != 0);

        uint32_t floor_log_2_d = 63 - __builtin_clzll(d);

        // Power of 2
        if ((d & (d - 1)) == 0) {
            magic = 0;
            more = (uint8_t) (floor_log_2_d);
        } else {
            uint64_t rem;
            auto proposed_m = div_64_to_64(1ULL << floor_log_2_d, 0, d, &rem);
            const auto e = d - rem;
            proposed_m += proposed_m;
            const uint64_t twice_rem = rem + rem;
            if (twice_rem >= d || twice_rem < rem) proposed_m += 1;
            more = (uint8_t) (floor_log_2_d | 0x40);
            magic = 1 + proposed_m;
        }
        more &= 0x3f;
    }

    friend uint64_t operator/(uint64_t numer, const divider_64 &d) {
        if (!d.magic) {
            return numer >> d.more;
        }
        auto q = mullhi_u64(d.magic, numer);
        auto t = ((numer - q) >> 1u) + q;
        return t >> d.more;
    }

    friend uint64_t operator%(uint64_t numer, const divider_64 &d) {
        return numer - (numer / d) * d.value;
    }
};

void solve(int test_number) {
    int n = nxt();
    divider_64 m = nxt();

    vector <uint64_t> dp(n + 1);
    vector <uint64_t> pref_sum(n + 1);
    dp[1] = 1;
    uint64_t s = 0;
    for (int i = 1; i <= n; ++i) {
        s += pref_sum[i];
        s = s % m;
        if (i > 1) dp[i] = s;

        if (i + 1 <= n) {
            pref_sum[i + 1] += dp[i];
        }

        for (int j = 2 * i; j <= n; j += i) {
            pref_sum[j] += dp[i] - dp[i - 1] + m.value;
        }
    }

    cout << dp[n] % m << "\n";
}

int main(int argc, char **argv) {
//    freopen("input", "r", stdin);
//    freopen("output.txt", "w", stdout);

    ::TTT = 1;
//    nxt();
    pre();

    for (int test = 1; test <= ::TTT; ++test) {
//        cout << "Case #" << test << ": ";
        solve(test);
    }

    return 0;
}

#ifdef LOCAL

struct timer {
    clock_t init;

    timer() {
        init = clock();
    }

    clock_t time() const {
        return clock() - init;
    }

    ~timer() {
        cerr << "Time elapsed: " << (double) (time()) / CLOCKS_PER_SEC * 1000 << " ms." << endl;
    }
};

#include <sys/resource.h>

struct init_str {
    timer t{};

    init_str() {
        freopen("input.txt", "r", stdin);
//        freopen("output.txt", "w", stdout);
    }

} init_global_;

#endif // LOCAL

//#define AUTO_MALLOC
#ifdef AUTO_MALLOC
namespace MALLOC {
    const size_t MAX_HEAP = 256 * 1000 * 1000;
    char buf[MAX_HEAP];
    size_t ptr;
}

void *operator new(size_t size) {
    void *result = MALLOC::buf + MALLOC::ptr;
    MALLOC::ptr += size;
    return result;
}

void operator delete(void *ptr) noexcept { /* DO NOTHING */ }

#endif //AUTO_MALLOC

template<typename T>
T gcd(T x, T y) {
    while (y > 0) {
        x %= y;
        swap(x, y);
    }
    return x;
}

template<class T>
T lcm(T a, T b) {
    return a / gcd(a, b) * b;
}

template<class _T>
inline _T sqr(const _T &x) {
    return x * x;
}

template<class _T>
inline string tostr(const _T &a) {
    ostringstream os("");
    os << a;
    return os.str();
}

template<typename T>
inline void input(T &a) {
    static int ed;
    a = 0;
    while (!isdigit(ed = getchar()) && ed != '-') {}
    char neg = 0;
    if (ed == '-') {
        neg = 1;
        ed = getchar();
    }
    while (isdigit(ed)) {
        a = 10 * a + ed - '0';
        ed = getchar();
    }
    if (neg) a = -a;
}

template<>
inline void input(string &a) {
    a.clear();
    static int ed;
    while (isspace(ed = getchar())) {}
    while (!isspace(ed) && ed != EOF) {
        a += (char) ed;
        ed = getchar();
    }
}

template<typename T>
inline T nxt() {
    T res;
    input(res);
    return res;
}

bool checkp(long long v) {
    if (v < 2) return false;
    for (long long i = 2; i * i <= v; ++i) {
        if (v % i == 0) {
            return false;
        }
    }
    return true;
}

template<typename T, typename N>
T pw(T a, N n, T m) {
    T res = 1;
    while (n) {
        if (n & 1) {
            res = res * a % m;
        }
        a = a * a % m;
        n >>= 1;
    }
    return res;
}

template<typename T>
T inv(T a, T p) {
    T res = 1;
    while (a > 1) {
        res = res * (p - p / a) % p;
        a = p % a;
    }
    return res;
}

template<class T>
bool uin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool uax(T &a, const T &b) {
    if (b > a) {
        a = b;
        return true;
    }
    return false;
}


#include <bits/stdc++.h>
using namespace std;

const int MAX = 4e6+1;
int spf[MAX] = {0, 1};
bool vis[MAX] = {0};
int dp[MAX] = {0, 1};
int divs[MAX] = {0};

vector<int> generate_divisors(int n) {
    int nc = n;
    vector<pair<int,int>> divisors;
    while(nc > 1) {
        divisors.push_back({spf[nc], 0});
        int i = divisors.size() - 1;
        while(nc % divisors[i].first == 0) {
            divisors[i].second++;
            nc /= divisors[i].first;
        }
    }

    vector<pair<int,int>> idx(divisors.size(), {1,0});
    vector<int> out;
    int x = 1;
    while(idx.size() > 0) {
        out.push_back(x);
        while(idx.size() > 0 && idx[idx.size()-1].second == divisors[idx.size()-1].second) {
            x /= idx[idx.size()-1].first;
            idx.pop_back();
        }
        if(idx.size() == 0) break;
        x *= divisors[idx.size() - 1].first;
        idx[idx.size()-1].first *= divisors[idx.size() - 1].first;
        idx[idx.size()-1].second++;
        while(idx.size() < divisors.size()) idx.push_back({1, 0});
    }
    return out;
}

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int n, MOD;
    cin >> n >> MOD;

    for(int i=2; i<=n; i++) {
        if(vis[i]) continue;
        for(int j=i; j<=n; j+=i) {
            if(vis[j]) continue;
            vis[j] = 1;
            spf[j] = i;
        }
    }

    int curr_dp_sum = dp[1];
    int curr_div_sum = 0;

    for(int i=2; i <= n; i++) {
        dp[i] = curr_dp_sum;
        vector<int> divisors = generate_divisors(i);
        for(auto &d: divisors) {
            if(d == 1) continue;
            curr_div_sum = (curr_div_sum + MOD - dp[divs[d]]) % MOD;
            divs[d]++;
            curr_div_sum = (curr_div_sum + dp[divs[d]]) % MOD;
        }
        dp[i] = (dp[i] + curr_div_sum) % MOD;
        curr_dp_sum = (curr_dp_sum + dp[i]) % MOD;
    }

    cout << dp[n] << "\n";
}


#include<bits/stdc++.h>
using namespace std;
int f[int(4e10) + 1];
long long g[int(4e10) + 1];
int main() {
    int n, m;
    cin >> n >> m;
    f[1] = 1
    for (int i = 2; i <= n; i++) {
        f[i] = ((f[i - 1] << 1) + g[i]) % m;
        if (i == 2) f[i] = 2;
        if (f[i] < 0) f[i] += m;
        for (int k = 2; k * i <= n; k++) {
            g[k * i] += f[i] - f[i - 1];
        }
    }
    cout << f[n] << endl;
    return 0;
}


#include <vector>
#include <array>
#include <stack>
#include <queue>
#include <list>
#include <bitset>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <string>
#include <chrono>
#include <random>
#include <cmath>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <functional>
#include <sstream>

#include <algorithm>
#include <array>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

#include <utility>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

struct barrett {
    unsigned int _m;
    unsigned long long im;

    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    unsigned int umod() const { return _m; }

    unsigned int mul(unsigned int a, unsigned int b) const {

        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <type_traits>
#include <vector>

namespace atcoder {

namespace internal {

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly(std::vector<mint>& a) {
    static constexpr int g = internal::primitive_root<mint::mod()>;
    int n = int(a.size());
    int h = internal::ceil_pow2(n);

    static bool first = true;
    static mint sum_e[30];  // sum_e[i] = ies[0] * ... * ies[i - 1] * es[i]
    if (first) {
        first = false;
        mint es[30], ies[30];  // es[i]^(2^(2+i)) == 1
        int cnt2 = bsf(mint::mod() - 1);
        mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
        for (int i = cnt2; i >= 2; i--) {
            es[i - 2] = e;
            ies[i - 2] = ie;
            e *= e;
            ie *= ie;
        }
        mint now = 1;
        for (int i = 0; i <= cnt2 - 2; i++) {
            sum_e[i] = es[i] * now;
            now *= ies[i];
        }
    }
    for (int ph = 1; ph <= h; ph++) {
        int w = 1 << (ph - 1), p = 1 << (h - ph);
        mint now = 1;
        for (int s = 0; s < w; s++) {
            int offset = s << (h - ph + 1);
            for (int i = 0; i < p; i++) {
                auto l = a[i + offset];
                auto r = a[i + offset + p] * now;
                a[i + offset] = l + r;
                a[i + offset + p] = l - r;
            }
            now *= sum_e[bsf(~(unsigned int)(s))];
        }
    }
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly_inv(std::vector<mint>& a) {
    static constexpr int g = internal::primitive_root<mint::mod()>;
    int n = int(a.size());
    int h = internal::ceil_pow2(n);

    static bool first = true;
    static mint sum_ie[30];  // sum_ie[i] = es[0] * ... * es[i - 1] * ies[i]
    if (first) {
        first = false;
        mint es[30], ies[30];  // es[i]^(2^(2+i)) == 1
        int cnt2 = bsf(mint::mod() - 1);
        mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
        for (int i = cnt2; i >= 2; i--) {
            es[i - 2] = e;
            ies[i - 2] = ie;
            e *= e;
            ie *= ie;
        }
        mint now = 1;
        for (int i = 0; i <= cnt2 - 2; i++) {
            sum_ie[i] = ies[i] * now;
            now *= es[i];
        }
    }

    for (int ph = h; ph >= 1; ph--) {
        int w = 1 << (ph - 1), p = 1 << (h - ph);
        mint inow = 1;
        for (int s = 0; s < w; s++) {
            int offset = s << (h - ph + 1);
            for (int i = 0; i < p; i++) {
                auto l = a[i + offset];
                auto r = a[i + offset + p];
                a[i + offset] = l + r;
                a[i + offset + p] =
                    (unsigned long long)(mint::mod() + l.val() - r.val()) *
                    inow.val();
            }
            inow *= sum_ie[bsf(~(unsigned int)(s))];
        }
    }
}

}  // namespace internal

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(std::vector<mint> a, std::vector<mint> b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};
    if (std::min(n, m) <= 60) {
        if (n < m) {
            std::swap(n, m);
            std::swap(a, b);
        }
        std::vector<mint> ans(n + m - 1);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans[i + j] += a[i] * b[j];
            }
        }
        return ans;
    }
    int z = 1 << internal::ceil_pow2(n + m - 1);
    a.resize(z);
    internal::butterfly(a);
    b.resize(z);
    internal::butterfly(b);
    for (int i = 0; i < z; i++) {
        a[i] *= b[i];
    }
    internal::butterfly_inv(a);
    a.resize(n + m - 1);
    mint iz = mint(z).inv();
    for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
    return a;
}

template <unsigned int mod = 998244353,
          class T,
          std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    using mint = static_modint<mod>;
    std::vector<mint> a2(n), b2(m);
    for (int i = 0; i < n; i++) {
        a2[i] = mint(a[i]);
    }
    for (int i = 0; i < m; i++) {
        b2[i] = mint(b[i]);
    }
    auto c2 = convolution(move(a2), move(b2));
    std::vector<T> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        c[i] = c2[i].val();
    }
    return c;
}

std::vector<long long> convolution_ll(const std::vector<long long>& a,
                                      const std::vector<long long>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    static constexpr unsigned long long MOD1 = 754974721;  // 2^24
    static constexpr unsigned long long MOD2 = 167772161;  // 2^25
    static constexpr unsigned long long MOD3 = 469762049;  // 2^26
    static constexpr unsigned long long M2M3 = MOD2 * MOD3;
    static constexpr unsigned long long M1M3 = MOD1 * MOD3;
    static constexpr unsigned long long M1M2 = MOD1 * MOD2;
    static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;

    static constexpr unsigned long long i1 =
        internal::inv_gcd(MOD2 * MOD3, MOD1).second;
    static constexpr unsigned long long i2 =
        internal::inv_gcd(MOD1 * MOD3, MOD2).second;
    static constexpr unsigned long long i3 =
        internal::inv_gcd(MOD1 * MOD2, MOD3).second;

    auto c1 = convolution<MOD1>(a, b);
    auto c2 = convolution<MOD2>(a, b);
    auto c3 = convolution<MOD3>(a, b);

    std::vector<long long> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        unsigned long long x = 0;
        x += (c1[i] * i1) % MOD1 * M2M3;
        x += (c2[i] * i2) % MOD2 * M1M3;
        x += (c3[i] * i3) % MOD3 * M1M2;
        long long diff =
            c1[i] - internal::safe_mod((long long)(x), (long long)(MOD1));
        if (diff < 0) diff += MOD1;
        static constexpr unsigned long long offset[5] = {
            0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
        x -= offset[diff % 5];
        c[i] = x;
    }

    return c;
}

}  // namespace atcoder

using namespace std;

using Mint = atcoder::modint998244353;

class Solution {
public:
    long long solve(int n, int K, int m) {

        vector<vector<Mint>> X(n + 1);
        X[1].resize(K + 1, 1);

        vector<Mint> sums(2 * K + 4, 0);
        for (int L = 2; L <= n; ++L) {

            X[L] = atcoder::convolution(X[L - 1], X[L - 1]);

            // int mx = min(K, m);
            // if (X[L].size() > mx + 1) {
            //     X[L].resize(mx + 1);
            // }
            int sz = X[L].size();
            sums[sz] = 0;
            for (int i = sz - 1; i >= 0; --i) {
                sums[i] = sums[i + 1] + X[L][i];
            }

            if (X[L].size() > K + 1) {
                X[L].resize(K + 1);
            }

            for (int i = 0; i < sz; ++i) {
                int choices = K - i + 1;
                X[L][i] *= choices;
                X[L][i] += sums[i + 1];
            }
        }

        Mint res = 0;
        for (int i = max(0, m - (int)(X[n].size() - 1)); i <= K && i <= m && i < X[n].size(); ++i) {
            Mint cnt = X[n][i] * X[n][m - i];
            res += cnt;
        }

        return res.val();
    }
};

int main(int argc, char** argv) {
    ios::sync_with_stdio(false);
    cin.tie(0);

    Solution sol;

    int n, K, F;
    cin >> n >> K >> F;

    cout << sol.solve(n, K, F) << '\n';

    return 0;
}


#pragma region template
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#ifdef __LOCAL
 #include <debug>
#else
 #define debug(...) void(0)
#endif

using ll=long long;
using ld=long double;
using vi=vector<int>;
using vll=vector<ll>;
using pi=pair<int,int>;
using pll=pair<ll,ll>;

#define overload2(a,b,c,...) c
#define overload3(a,b,c,d,...) d
#define overload4(a,b,c,d,e,...) e
#define overload5(a,b,c,d,e,f,...) f

#define TYPE1(T) template<typename T>
#define TYPE2(T,U) template<typename T,typename U>
#define TYPE(...) overload2(__VA_ARGS__,TYPE2,TYPE1)(__VA_ARGS__)
#define TYPES1(T) template<typename... T>
#define TYPES2(H,T) template<typename H,typename... T>
#define TYPES(...) overload2(__VA_ARGS__,TYPES2,TYPES1)(__VA_ARGS__)

#define REP4(i,s,n,d) for(int i=(s);i<(n);i+=(d))
#define REP3(i,s,n) REP4(i,s,n,1)
#define REP2(i,n) REP3(i,0,n)
#define REP1(n) REP2(tomato,n)
#define REP(...) overload4(__VA_ARGS__,REP4,REP3,REP2,REP1)(__VA_ARGS__)

#define RREP4(i,s,n,d) for(int i=(n)-1;i>=s;i-=d)
#define RREP3(i,s,n) RREP4(i,s,n,1)
#define RREP2(i,n) RREP3(i,0,n)
#define RREP1(n) RREP2(tomato,n)
#define RREP(...) overload4(__VA_ARGS__,RREP4,RREP3,RREP2,RREP1)(__VA_ARGS__)

#define ALL(v) v.begin(),v.end()
#define RALL(v) v.rbegin(),v.rend()
#define SORT(v) sort(ALL(v))
#define RSORT(v) sort(RALL(v))
#define REVERSE(v) reverse(ALL(v))
#define UNIQUE(v) SORT(v),v.erase(unique(ALL(v)),v.end())

TYPES(T) void input(T&... a){ (cin>>...>>a); }
#define DECLARE(T,...) T __VA_ARGS__;input(__VA_ARGS__);
#define INT(...) DECLARE(int,__VA_ARGS__)
#define STR(...) DECLARE(string,__VA_ARGS__)
#define LL(...) DECLARE(long long,__VA_ARGS__)
#define CHR(...) DECLARE(char,__VA_ARGS__)
#define DBL(...) DECLARE(double,__VA_ARGS__)
#define VI(n,v) vi v(n);cin>>v;

TYPE(T) istream&operator>>(istream&is,vector<T>&v){
  for(auto&a:v)cin>>a;
  return is;
}
TYPE(T) ostream&operator<<(ostream&os,vector<T>&v){
  if(&os==&cerr)os<<"[";
  REP(i,v.size()){
    os<<v[i];
    if(i+1<v.size())os<<(&os==&cerr?",":" ");
  }
  if(&os==&cerr)os<<"]";
  return os;
}
TYPE(T,S) istream&operator>>(istream&is,pair<T,S>&p){
  cin>>p.first>>p.second;
  return is;
}

TYPE(T) using pq=priority_queue<T>;
TYPE(T) using pgq=priority_queue<T,vector<T>,greater<T>>;
TYPE(T) T pick(queue<T>& que){assert(que.size()); T a=que.front();que.pop();return a;}
TYPE(T) T pick(pq<T>& que){assert(que.size()); T a=que.top();que.pop();return a;}
TYPE(T) T pick(stack<T>& sta){assert(sta.size()); T a=sta.top();sta.pop();return a;}

string YES(bool f=true){return (f?"YES":"NO");}
string Yes(bool f=true){return (f?"Yes":"No");}
string yes(bool f=true){return (f?"yes":"no");}

vi iota(int n){vi a(n);iota(ALL(a),0);return a;}

constexpr int INF=1e9+7;
constexpr ll LINF=1e18+7;

TYPE(T) void fin(T a){cout<<a<<endl;exit(0);}

struct r2{
  int y,x;
  bool operator<(const r2&a){return (y!=a.y?y<a.y:x<a.x);}
  bool operator>(const r2&a){return (y!=a.y?y>a.y:x>a.x);}
  bool operator==(const r2&a){return (y==a.y and x==a.x);}
};
#pragma endregion template

#include <atcoder/modint>
#include <atcoder/convolution>
using namespace atcoder;
using mint=modint998244353;
ostream& operator<<(ostream &os,mint a){os<<a.val();return os;}
istream& operator>>(istream &is,mint &a){
  long long b;is>>b;a=b;
  return is;
}

int main(){
  ios::sync_with_stdio(false);
  cin.tie(nullptr);

  INT(n,k,f);
  vector<mint> F(k+1);
  REP(i,k+1)F[i]=i<=k;
  REP(h,2,n+1){
    auto G=convolution(F,F);
    REP(i,k+1)F[i]=(k-i)*G[i];
    mint sum=0;
    RREP(i,G.size()){
      sum+=G[i];
      if(i<=k)F[i]+=sum;
    }
  }
  mint ans=0;
  REP(i,f+1)if(i<=k and f-i<=k)ans+=F[i]*F[f-i];
  cout<<ans<<endl;
}


#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <bitset>
#include <deque>
#include <queue>
#include <tuple>
#include <cmath>
#include <cctype>
#include <stack>
#include <cassert>
#include <iomanip>
#include <complex>
using namespace std;
using ll = long long;
using cd = complex<long double>;
ll MOD = 998244353;

int n, k, f;

void fft(vector<cd>& p, bool invert) {
    ll n = p.size();
    vector<int> rev(n); rev[0] = 0;
    for (int i = 1; i < n; i++) {
        rev[i] = (rev[i>>1]>>1) + (i%2 ? n/2 : 0);
        if (i < rev[i]) swap(p[i], p[rev[i]]);
    }
    vector<cd> w(n);
    for (int i = 0; i < n; i++) w[i] = polar(1.0, ll(2*i)*M_PI / n * (invert ? -1 : 1));
    for (int len = 1; len < n; len *= 2) {
        int m = n / len / 2;
        for (int i = 0; i < n; i += 2*len) {
            for (int j = 0; j < len; j++) {
                cd even = p[i+j], odd = p[i+j+len];
                p[i+j] = even + w[m*j]*odd;
                p[i+j+len] = even - w[m*j]*odd;
            }
        }
    }
    if (invert)
        for (cd& x : p) x /= n;
}
vector<ll> conv_mod(const vector<ll> a, const vector<ll> b) {
    int d = a.size()+b.size()-1;
    int n2 = 1; while (n2 <= d) n2 *= 2;
    ll M = sqrt(MOD);
    vector<cd> inf(n2), ins(n2), outf(n2), outs(n2);
    for (int i = 0; i < a.size(); i++) inf[i] = cd(a[i]/M, a[i]%M);
    for (int i = 0; i < b.size(); i++) ins[i] = cd(b[i]/M, b[i]%M);
    fft(inf, false); fft(ins, false);
    //cout << "debugging inf, ins" << endl;
    //for (int i = 0; i < n2; i++) cout << inf[i] << " "; cout << endl;
    //for (int i = 0; i < n2; i++) cout << ins[i] << " "; cout << endl;
    for (int i = 0; i < n2; i++) {
        int j = n2-i;
        outf[i] = (inf[i] + conj(inf[j]))*ins[i] / cd(2);
        outs[i] = (inf[i] - conj(inf[j]))*ins[i] / cd(2) / cd(0, 1);
    }
    fft(outf, true); fft(outs, true);
    //cout << "debugging outf, outs" << endl;
    //for (int i = 0; i < n2; i++) cout << outf[i] << " "; cout << endl;
    //for (int i = 0; i < n2; i++) cout << outs[i] << " "; cout << endl;
    vector<ll> res(d+1);
    for (int i = 0; i <= d; i++) {
        ll a = llround(outf[i].real()), c = llround(outs[i].imag());
        ll b = llround(outf[i].imag() + outs[i].real());
        res[i] = ((a%MOD*M + b)%MOD*M + c)%MOD;
    }
    return res;
}

vector<ll> naive_mult(vector<ll> a, vector<ll> b) {
    vector<ll> res(a.size()-1+b.size()-1+1, 0);
    for (int i = 0; i < a.size(); i++) {
        for (int j = 0; j < b.size(); j++) {
            res[i+j] = (res[i+j] + a[i]*b[j]) % MOD;
        }
    }
    return res;
}

int main() {
    cin >> n >> k >> f;
    vector<ll> p(k+1, 1);
    for (int i = 2; i <= n; i++) {
        vector<ll> v = conv_mod(p, p);
        ll rs = 0;
        for (int i = v.size()-1; i >= 0; i--) {
            if (i <= k) p[i] = (ll(k+1-i)*v[i] + rs) % MOD;
            rs = (rs + v[i]) % MOD;
        }
    }
    p = conv_mod(p, p);
    cout << (f < p.size() ? p[f] : 0) << endl;

    //cout << "debugging conv_mod" << endl;
    //vector<ll> a{1, 2}, b{2, 3};
    //vector<ll> res = conv_mod(a, b);
    //for (int i = 0; i < res.size(); i++) cout << res[i] << " "; cout << endl;

}


#include <bits/stdc++.h>

using namespace std;

#define mp make_pair
#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define fi first
#define se second
#define ff fi.fi
#define ss se.se
#define fs fi.se
#define sf se.fi
#define all(x) x.begin(), x.end()
#define endl "\n"

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
const ll MOD = 998244353;
namespace FFT {
  /* ----- Adjust the constants here ----- */
  const int LN = 23; //23
  const int N = 1 << LN;
  typedef int LL; // 2**23 * 119 + 1. 998244353
// `MOD` must be of the form 2**`LN` * k + 1, where k odd.
  const LL MOD = 998244353; // 2**24 * 54975513881 + 1.
  const LL PRIMITIVE_ROOT = 3; // Primitive root modulo `MOD`.
  /* ----- End of constants ----- */
  LL root[N];
  inline LL power(LL x, LL y) {
    LL ret = 1;
    for(; y; y >>= 1) {
      if(y & 1)
        ret = (__int128) ret * x % MOD;
      x = (__int128) x * x % MOD;
    }
    return ret;
  }
  inline void init_fft() {
    const LL UNITY = power(PRIMITIVE_ROOT, MOD - 1 >> LN);
    root[0] = 1;
    for(int i = 1; i < N; i++)
      root[i] = (__int128) UNITY * root[i - 1] % MOD;
    return;
  }
// n = 2^k is the length of polynom
  inline void fft(int n, vector<LL>& a, bool invert) {
    for(int i = 1, j = 0; i < n; ++i) {
      int bit = n >> 1;
      for(; j >= bit; bit >>= 1)
        j -= bit;
      j += bit;
      if(i < j)
        swap(a[i], a[j]);
    }
    for(int len = 2; len <= n; len <<= 1) {
      LL wlen = (invert ? root[N - N / len] : root[N / len]);
      for(int i = 0; i < n; i += len) {
        LL w = 1;
        for(int j = 0; j<len >> 1; j++) {
          LL u = a[i + j];
          LL v = (__int128) a[i + j + len / 2] * w % MOD;
          a[i + j] = ((__int128) u + v) % MOD;
          a[i + j + len / 2] = ((__int128) u - v + MOD) % MOD;
          w = (__int128) w * wlen % MOD;
        }
      }
    }
    if(invert) {
      LL inv = power(n, MOD - 2);
      for(int i = 0; i < n; i++)
        a[i] = (__int128) a[i] * inv % MOD;
    }
    return;
  }
  inline vector<LL> multiply(vector<LL> a, vector<LL> b) {
    vector<LL> c;
    int len = 1 << 32 - __builtin_clz(a.size() + b.size() - 2);
    a.resize(len, 0);
    b.resize(len, 0);
    fft(len, a, false);
    fft(len, b, false);
    c.resize(len);
    for(int i = 0; i < len; ++i)
      c[i] = (__int128) a[i] * b[i] % MOD;
    fft(len, c, true);
    return c;
  }
//FFT::init_fft(); wajib di panggil init di awal
}
vector<int> v;

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	FFT::init_fft();
	ll n,k,f;cin>>n>>k>>f;
	for(int i=0;i<=k;i++){
		v.pb(1LL);
	}
	//kerjain per level
	for(int i=2;i<=n;i++){
		v=FFT::multiply(v,v);
		// trus tambahin yang belakangnya
		ll jum=0LL;
		for(int j=v.size()-1;j>=0;j--){
			jum+=v[j];
			jum%=MOD;
			if(j<=k)v[j]=(((max(0LL,(k-j))*(ll)v[j])%MOD)+jum)%MOD;
		}
		v.resize(k+1);
//		cerr<<"-------------------- "<<i<<endl;
//		for(int j=0;j<v.size();j++){
//			cerr<<v[j]<<" ";
//		}
//		cerr<<endl;
	}
	ll ans=0;
	for(int i=0;i<=k;i++){
//		if(f-i>=0 && f-i<=k){
//			ans+= (ll)v[i]*v[f-i]%MOD;
//		}
		if(f-i<0 || f-i>k)continue;
		ans+=((ll)v[i]*(ll)v[f-i])%MOD;
		ans%=MOD;
	}
	cout<<ans%MOD<<endl;
	return 0;
}


/*
СТРОИМ СТЕНУ РАБОТЯГИ!
█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█
█═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═█
█═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═█
█═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═█
█═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═█
█═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═█
█═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═█
█═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═█
█═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═╩═╦═█
█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█
*/
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>

using namespace std;

template<typename T1, typename T2>inline void chkmin(T1 &x, T2 y) { if (x > y) x = y; }
template<typename T1, typename T2>inline void chkmax(T1 &x, T2 y) { if (x < y) x = y; }
/** Interface */

inline int readChar();
template <class T = int> inline T readInt();
template <class T> inline void writeInt( T x, char end = 0 );
inline void writeChar( int x );
inline void writeWord( const char *s );

/** Read */

static const int buf_size = 4096;

inline int getChar() {
    static char buf[buf_size];
    static int len = 0, pos = 0;
    if (pos == len) {
        pos = 0, len = fread(buf, 1, buf_size, stdin);
    }
    if (pos == len) {
        return -1;
    }
    return buf[pos++];
}

inline int readChar() {
    int c = getChar();
    while (c <= 32) {
        c = getChar();
    }
    return c;
}

template <class T>
inline T readInt() {
    int s = 1, c = readChar();
    T x = 0;
    if (c == '-')
        s = -1, c = getChar();
    while ('0' <= c && c <= '9')
        x = x * 10 + c - '0', c = getChar();
    return s == 1 ? x : -x;
}

/** Write */

static int write_pos = 0;
static char write_buf[buf_size];

inline void writeChar( int x ) {
    if (write_pos == buf_size)
        fwrite(write_buf, 1, buf_size, stdout), write_pos = 0;
    write_buf[write_pos++] = x;
}

template <class T>
inline void writeInt( T x, char end ) {
    if (x < 0)
        writeChar('-'), x = -x;

    char s[24];
    int n = 0;
    while (x || !n)
        s[n++] = '0' + x % 10, x /= 10;
    while (n--)
        writeChar(s[n]);
    if (end)
        writeChar(end);
}

inline void writeWord( const char *s ) {     while (*s)
writeChar(*s++); }

struct Flusher {
    ~Flusher() {
        if (write_pos)
            fwrite(write_buf, 1, write_pos, stdout), write_pos = 0;
    }
} flusher;

using namespace std;

#define sz(c) (int)(c).size()
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define left left228
#define right right228
#define next next228
#define rank rank228
#define prev prev228
const int MAXN = 5228;

int sz[MAXN];
vector<int> edges[MAXN], st;
int dp[2 * MAXN];
int n;
int a, b, c, d;

int dfs(int v) {
    sz[v] = 0;
    if (edges[v].empty()) {
        sz[v] = 1;
    }
    int ans = 0;
    if (v == a) {
        ans = 1;
    }
    if (v == b) {
        ans = 2;
    }
    if (v == c) {
        ans = 3;
    }
    if (v == d) {
        ans = 4;
    }
    for (auto u: edges[v]) {
        int k = dfs(u);
        chkmax(ans, k);
        sz[v] += sz[u];
    }
    return ans;
}

int sza, szb, szc, szd;

int main() {
 	n = readInt();
    a = readInt(), b = readInt(), c = readInt(), d = readInt();
    a--, b--, c--, d--;
    for (int i = 1; i < n; i++) {
        int p = readInt(), p--;
        edges[p].push_back(i);
    }
    for (int u: edges[0]) {
        int x = dfs(u);
        sz[0] += sz[u];
        if (x == 0) {
            st.push_back(sz[u]);
        } else if (x == 1) {
            sza = sz[u];
        } else if (x == 2) {
            szb = sz[u];
        } else if (x == 3) {
            szc = sz[u];
        } else if (x == 4) {
            szd = sz[u];
        }
    }
    if (sz[0] % 2 != 0) {
        cout << "NO\n";
        return 0;
    }
    int sum = 0;
    for (int i: st) {
        sum += i;
    }
    dp[0] = 1;
    for (int i: st) {
        for (int j = n - i; j >= 0; j--) {
            dp[j + i] |= dp[j];
        }
    }
    bool good = 0, good1 = 0;
    for (int i = 0; i <= n; i++) {
        if (!dp[i]) {
            continue;
        }
        int x = i + szc - (sum - i + szd);
        int gg = sza + szb - 2;
        if (abs(x) <= gg) {
            good = 1;
        }
    }
    for (int i = 0; i <= n; i++) {
        if (!dp[i]) {
            continue;
        }
        int x = i + sza - (sum - i + szb);
        int gg = szc - szd - 2;
        if (abs(x) <= gg) {
            good1 = 1;
        }
    }
    if (good && good1) {
        writeWord("YES\n");
    } else {
        writeWord("NO\n");
    }
	return 0;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

const int MOD = 1000000007;
const ll INF = 1e18;
const int MX = 10101; //check the limits, dummy

vector<vi> graph;
int subsize[MX];
int spec[MX];
int data[4];
int totalSize[4];

int dfs(int v, int p) {
    spec[v] = -1;
    F0R(i, 4) if (v == data[i]) spec[v] = i;
    int cur = 1;
    F0R(i, sz(graph[v])) {
        int nxt = graph[v][i];
        if (nxt == p) continue;
        cur += dfs(nxt, v);
        spec[v] = max(spec[v], spec[nxt]);
    }
    subsize[v] = cur;
    return cur;
}

bool possPos[MX][4];

void computePoss(int p) {
    bool curPoss[MX];
    F0R(i, MX) curPoss[i] = false;
    curPoss[2] = true;
    int v = 0;
    F0R(i, sz(graph[0])) {
        if (spec[graph[0][i]] == p) v = graph[0][i];
    }
//    cout << v << endl;
    int lst = 0;
    totalSize[p] = subsize[v];
    while (v != data[p]) {
//        cout << p << " " << v << " TEST" << endl;
        F0Rd(i, MX) {
            if (curPoss[i]) curPoss[i+1] = true;
            curPoss[i] = false;

        }
/*        F0R(i, 20) {
            cout << p << " " << v << " " << i << " " << (curPoss[i] ? "YES" : "NO") << endl;
        }*/

        F0R(i, sz(graph[v])) {
            int nxt = graph[v][i];
            if (nxt == lst) continue;
            if (spec[nxt] >= 0) continue;
//            cout <<nxt << " " << " " << spec[7] << " " << subsize[nxt] << endl;
            F0Rd(j, MX) {
                if (curPoss[j]) {
                    curPoss[j+subsize[nxt]*2] = true;
                }
            }
        }

        F0R(i, sz(graph[v])) {
            int nxt = graph[v][i];
            if (nxt != lst && spec[nxt] == p) {
                lst = v;
                v = nxt;
                break;
            }
        }
    }
    F0R(i, MX) {
        possPos[i][p] = curPoss[i];
    }
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
    int N; cin >> N;
    F0R(i, N) {
        vi blank; graph.pb(blank);
    }
    F0R(i, 4) cin >> data[i];
    F0R(i, 4) data[i]--;
    FOR(i, 1, N) {
        int P; cin >> P; P--;
        graph[P].pb(i); graph[i].pb(P);
    }

    dfs(0, -1);
/*    F0R(i, N) cout << spec[i] << " ";
    cout << endl;*/

    F0R(i, 4) computePoss(i);

    F0R(i, 4) {
        F0R(j, 20) {
//            cout << i << " " << j << " " << (possPos[j][i] ? "YES" : "NO") << endl;
        }
    }

    bool possOne[MX], possTwo[MX];
    F0R(i, MX) {
        F0R(j, MX) {
            if (possPos[i][0] && possPos[j][1]) {
                int val = 2*totalSize[0] - i + j - 1;
                possOne[val] = true;
            }
            if (possPos[i][2] && possPos[j][2]) {
                int val = 2*totalSize[2] - i + j - 1;
                possTwo[val] = true;
            }
        }
    }

    F0Rd(i, MX) {
        if (possOne[i]) {
            possOne[i+2*totalSize[2]] = true;
        }
        possOne[i] = false;
    }

    F0Rd(i, MX) {
        if (possTwo[i]) {
            possTwo[i+2*totalSize[0]] = true;
        }
        possTwo[i] = false;
    }

    F0R(i, sz(graph[0])) {
        int nxt = graph[0][i];
        if (spec[nxt] >= 0) continue;
        F0Rd(j, MX) {
            if (possOne[j]) {
                possOne[j+2*subsize[nxt]] = true;
            }
            if (possTwo[j]) {
                possTwo[j + 2*subsize[nxt]] = true;
            }
        }
    }

    cout << (possOne[N-2] && possTwo[N-2] ? "YES" : "NO") << endl;

	return 0;
}

// read the question correctly (ll vs int)
// template by bqi343


#pragma region Macros
#pragma GCC optimize("O3")
#pragma GCC target("avx2,avx")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define rep2(i, a, b) for(ll i = a; i <= b; ++i)
#define rep(i, n) for(ll i = 0; i < n; ++i)
#define rep3(i, a, b) for(ll i = a; i >= b; --i)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pb push_back
#define eb emplace_back
#define vi vector<int>
#define vll vector<ll>
#define vpi vector<pii>
#define vpll vector<pll>
#define overload2(_1, _2, name, ...) name
#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define VEC(type, name, size)                                                                                \
    vector<type> name(size);                                                                                \
    IN(name)
#define vv(type, name, h, ...) vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define VV(type, name, h, w)                                                                                \
    vector<vector<type>> name(h, vector<type>(w));                                                                                \
    IN(name)
#define vvv(type, name, h, w, ...) vector<vector<vector<type>>> name(h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)                                                                                \
    vector<vector<vector<vector<type>>>> name(a, vector<vector<vector<type>>>(b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))
#define fi first
#define se second
#define all(c) begin(c), end(c)
#define lb(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define ub(c, x) distance((c).begin(), upper_bound(all(c), (x)))
using namespace std;
string YES[2] = {"NO", "YES"};
string Yes[2] = {"No", "Yes"};
string yes[2] = {"no", "yes"};
template <class T> using pq = priority_queue<T>;
template <class T> using pqg = priority_queue<T, vector<T>, greater<T>>;
#define si(c) (int)(c).size()
#define INT(...)                                                                                \
    int __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define LL(...)                                                                                \
    ll __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define STR(...)                                                                                \
    string __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define CHR(...)                                                                                \
    char __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
#define DBL(...)                                                                                \
    double __VA_ARGS__;                                                                                \
    IN(__VA_ARGS__)
int scan() { return getchar(); }
void scan(int &a) { cin >> a; }
void scan(long long &a) { cin >> a; }
void scan(char &a) { cin >> a; }
void scan(double &a) { cin >> a; }
void scan(string &a) { cin >> a; }
template <class T, class S> void scan(pair<T, S> &p) { scan(p.first), scan(p.second); }
template <class T> void scan(vector<T> &);
template <class T> void scan(vector<T> &a) {
    for(auto &i : a) scan(i);
}
template <class T> void scan(T &a) { cin >> a; }
void IN() {}
template <class Head, class... Tail> void IN(Head &head, Tail &... tail) {
    scan(head);
    IN(tail...);
}
template <class T, class S> inline bool chmax(T &a, S b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T, class S> inline bool chmin(T &a, S b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
vi iota(int n) {
    vi a(n);
    iota(all(a), 0);
    return a;
}
template <typename T> vi iota(vector<T> &a, bool greater = false) {
    vi res(a.size());
    iota(all(res), 0);
    sort(all(res), [&](int i, int j) {
        if(greater) return a[i] > a[j];
        return a[i] < a[j];
    });
    return res;
}
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())
vector<pll> factor(ll x) {
    vector<pll> ans;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0) {
            ans.push_back({i, 1});
            while((x /= i) % i == 0) ans.back().second++;
        }
    if(x != 1) ans.push_back({x, 1});
    return ans;
}
template <class T> vector<T> divisor(T x) {
    vector<T> ans;
    for(T i = 1; i * i <= x; i++)
        if(x % i == 0) {
            ans.pb(i);
            if(i * i != x) ans.pb(x / i);
        }
    return ans;
}
template <typename T> void zip(vector<T> &x) {
    vector<T> y = x;
    sort(all(y));
    for(int i = 0; i < x.size(); ++i) { x[i] = lb(y, x[i]); }
}
int popcount(ll x) { return __builtin_popcountll(x); }
struct Setup_io {
    Setup_io() {
        ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        cout << fixed << setprecision(15);
    }
} setup_io;
int in() {
    int x;
    cin >> x;
    return x;
}
ll lin() {
    unsigned long long x;
    cin >> x;
    return x;
}

template <typename T> struct edge {
    int from, to;
    T cost;
    int id;
    edge(int to, T cost) : from(-1), to(to), cost(cost) {}
    edge(int from, int to, T cost) : from(from), to(to), cost(cost) {}
    edge(int from, int to, T cost, int id) : from(from), to(to), cost(cost), id(id) {}
    edge &operator=(const int &x) {
        to = x;
        return *this;
    }
    operator int() const { return to; }
};
template <typename T> using Edges = vector<edge<T>>;

using Tree = vector<vector<int>>;
using Graph = vector<vector<int>>;
template <class T> using Wgraph = vector<vector<edge<T>>>;
Graph getG(int n, int m = -1, bool directed = false, int margin = 1) {
    Tree res(n);
    if(m == -1) m = n - 1;
    while(m--) {
        int a, b;
        cin >> a >> b;
        a -= margin, b -= margin;
        res[a].emplace_back(b);
        if(!directed) res[b].emplace_back(a);
    }
    return move(res);
}
template <class T> Wgraph<T> getWg(int n, int m = -1, bool directed = false, int margin = 1) {
    Wgraph<T> res(n);
    if(m == -1) m = n - 1;
    while(m--) {
        int a, b;
        T c;
        cin >> a >> b >> c;
        a -= margin, b -= margin;
        res[a].emplace_back(b, c);
        if(!directed) res[b].emplace_back(a, c);
    }
    return move(res);
}

#define i128 __int128_t
#define ull unsigned long long int
#define TEST                                                                                \
    INT(testcases);                                                                                \
    while(testcases--)
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    for(auto &e : v) cout << e << " ";
    cout << endl;
    return os;
}
template <class T, class S> ostream &operator<<(ostream &os, const pair<T, S> &p) {
    cout << "(" << p.fi << ", " << p.se << ")";
    return os;
}
template <class S, class T> string to_string(pair<S, T> p) { return "(" + to_string(p.first) + "," + to_string(p.second) + ")"; }
template <class A> string to_string(A v) {
    if(v.empty()) return "{}";
    string ret = "{";
    for(auto &x : v) ret += to_string(x) + ",";
    ret.back() = '}';
    return ret;
}

void dump() { cerr << endl; }
template <class Head, class... Tail> void dump(Head head, Tail... tail) {
    cerr << to_string(head) << " ";
    dump(tail...);
}
#define endl '\n'
#ifdef _LOCAL
#undef endl
#define debug(x)                                                                                \
    cout << #x << ": ";                                                                                \
    dump(x)
#else
#define debug(x)
#endif
// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

// int rnd(int n) { return uniform_int_distribution<int>(0, n - 1)(rng); }
// ll rndll(ll n) { return uniform_int_distribution<ll>(0, n - 1)(rng); }

template <typename T> static constexpr T inf = numeric_limits<T>::max() / 2;
#pragma endregion

int main() {
    INT(n);
    VEC(int, a, 4);
    rep(i, 4) a[i]--;
    Graph g(n);
    vi par(n);
    rep2(i, 1, n - 1) {
        INT(p);
        g[--p].eb(i);
        par[i] = p;
    }
    using B = bitset<5014>;
    vi sub(n);
    {
        auto dfs = [&](auto &&f, int x) -> int {
            sub[x] = !g[x].size();
            for(auto e : g[x]) sub[x] += f(f, e);
            return sub[x];
        };
        dfs(dfs, 0);
    }
    if(sub[0] & 1) {
        cout << -1 << endl;
        exit(0);
    }
    {
        vi used(n);
        B b[4];
        vi cnt(4);
        rep(i, 4) {
            int now = a[i];
            int pre = 0;
            b[i].set(0);
            while(now) {
                for(auto e : g[now])
                    if(e != pre) b[i] = b[i] | (b[i] << sub[e]);
                pre = now;
                if(!par[now]) used[now] = true, cnt[i] = sub[now];
                now = par[now];
            }
        }
        B bit;
        bit[0] = 1;
        for(auto e : g[0]) {
            if(!used[e]) bit = bit | (bit << sub[e]);
        }
        int ch = sub[0] / 2 - 1;
        bool flag = true;
        auto f = [](const B &x, const B &y) {
            B res;
            rep(i, 5001) if(y[i]) res |= x << i;
            return res;
        };
        // rep(i, 4) cout << b[i] << endl;
        // cout << bit << endl;
        // cout << cnt[0] << " " << cnt[2] << endl;
        // cout << ch << endl;
        // int check = 0;
        if(ch - cnt[2] >= 0 and f(f(b[0], b[1]), bit)[ch - cnt[2]]) check |= 1;
        if(ch - cnt[0] >= 0 and f(f(b[2], b[3]), bit)[ch - cnt[0]]) check |= 2;
        cout << YES[check == 3] << endl;
    }
}


#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
const int N = 5005;
int n,v[5],sz[N],l[N],type[N],F[N],leaf[N];
vector <int> p[N],temp,a[6],f[N];
bool ck1 = false,ck2 = false;
void DFS(int u)
{
    int pos;
    sz[u]++;
    for (int id = 0; id < p[u].size();id++)
    {
        int v = p[u][id];
        DFS(v);
        sz[u] += sz[v];
        l[u] += l[v];
        type[u] = max(type[u],type[v]);
        if(type[v] > 0) pos = id;
    }
    if(p[u].size() == 0)
    {
        l[u] = 1;
        for (int i = 1;i <= 4;i++) if(v[i] == u) type[u] = i;
    }
    else swap(p[u][0],p[u][pos]);
    return;
}

void DFS1(int u)
{
    f[u].resize(l[u] + 1);
    fill(f[u].begin(),f[u].end(),0);
    int time = 0;
    for (int id = 0;id < p[u].size();id++)
    {
        int v = p[u][id];
        if((u == 1) && (!type[v]))
        {
            a[0].push_back(l[v]);
            continue;
        }
        DFS1(v);
        if(type[v] > 0)
        {
            time = l[v];
            for (int i = 0;i <= l[v];i++) f[u][i] = f[v][i];
        }
        else
        {
            for (int i = 0; i <= time;i++) temp[i] = f[u][i];
            for (int i = 0; i <= l[v];i++)
                for (int j = 0;j <= time;j++) if((temp[j]) && (f[v][i])) f[u][i + j] = 1;
            time += l[v];
        }
        if(u == 1)
        {
            leaf[type[v]] = l[v];
            int pos = type[v];
            a[pos].resize(f[v].size());
            for (int i = 0;i < f[v].size();i++) a[pos][i] = f[v][i];
        }
        f[v].clear();
    }
    if(p[u].size() == 0) f[u][1] = 1;
    return;
}

void dp()
{
    F[0] = 1;
    if(a[0].size() == 0) return;
    fill(F + 1,F + n + 1,0);
    F[a[0][0]] = 1;
    for (int i = 1;i < a[0].size();i++)
    {
        for (int j = 1;j <= n;j++) temp[j] = F[j];
        for (int j = 1;j + a[0][i] <= n;j++) if(temp[j]) F[j + a[0][i]] = 1;
    }
}
bool check(int x,int y,int z)
{
    if(l[1] % 2 == 1) return false;
    for (int i = 1;i < a[x].size();i++)
        for (int j = 1;j < a[y].size();j++)
            if(a[x][i] && a[y][j])
            {
                int leafs = l[1]`/2 - (leaf[x] - i) - j - leaf[z];
                if(F[leafs]) return true;
            }
    return false;
}
int main()
{
    //freopen("in.inp","r",stdin);
    scanf("%d",&n);
    for (int i = 1;i <= 4;i++) scanf("%d",&v[i]);
    for (int i = 2;i <= n;i++)
    {
        int x;
        scanf("%d",&x);
        p[x].push_back(i);
    }
    temp.resize(n + 1);
    DFS(1);
    DFS1(1);
    dp();
    ck1 = check(1,2,3) && (check(3,4,2));
    ck2 = check(1,2,4) && (check(3,4,2));
    if(ck1 || ck2) printf("YES"); else printf("NO");
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define N 200005

int n, l[N], r[N], cnt = 0;

map <int, int> used;

struct seg
{
	int l, r, coll, colr, cnt, tag;
}tr[N << 8];

struct SEG
{
	void build(int rt, int l, int r)
	{
		tr[rt].l = l, tr[rt].r = r;
		if(l == r)
		{
			return;
		}
		int mid = l + r >> 1;
		build(rt << 1, l, mid);
		build(rt << 1 | 1, mid + 1, r);
	}

	void Pushdown(int rt)
	{
		if(tr[rt].tag)
		{
			tr[rt << 1].tag = tr[rt << 1 | 1].tag = 1;
			tr[rt << 1].cnt = tr[rt << 1 | 1].cnt = 1;
			tr[rt << 1].coll = tr[rt << 1].colr = 1;
			tr[rt << 1 | 1].coll = tr[rt << 1 | 1].colr = 1;
		}
	}

	void Pushup(int rt)
	{
		tr[rt].cnt = tr[rt << 1].cnt + tr[rt << 1 | 1].cnt;
		tr[rt].coll = tr[rt << 1].coll, tr[rt].colr = tr[rt << 1 | 1].colr;
		if(tr[rt << 1].colr == 1 && tr[rt << 1 | 1].coll == 1) tr[rt].cnt--;
	}

	void update(int rt, int x, int y)
	{
		Pushdown(rt);
		int l = tr[rt].l, r = tr[rt].r, mid = l + r >> 1;
		// cout << l << ' ' << r << ' ' << x << ' ' << y << endl;
		if(l == x && r == y)
		{
			tr[rt].cnt = 1, tr[rt].tag = 1, tr[rt].coll = 1, tr[rt].colr = 1;
			return;
		}
		if(y <= mid) update(rt << 1, x, y);
		else if(x > mid) update(rt << 1 | 1, x, y);
		else update(rt << 1, x, mid), update(rt << 1 | 1, mid + 1, y);
		Pushup(rt);
	}
}tree;

int main()
{
	freopen("color.in","r",stdin);
	freopen("color.out","w",stdout);
	scanf("%d", &n);
	int maxn = 0;
	for(int i = 1; i <= n; i++)
	{
		scanf("%d%d", &l[i], &r[i]);
		r[i]--;
		maxn = max(maxn, r[i] + 1);
		if(used[l[i]] == 0)
		{
			used[l[i]] = ++cnt;
		}
		if(used[r[i]] == 0)
		{
			used[r[i]] = ++cnt;
		}
		if(used[r[i] + 1] == 0)
		{
			used[r[i] + 1] = ++cnt;
		}
	}

	tree.build(1, 1, maxn);
	for(int i = 1; i <= n; i++)
	{
		tree.update(1, l[i], r[i]);
		cout << tr[1].cnt << endl;
	}
	return 0;
}


///God help me.

#include<bits/stdc++.h>

using namespace std;

#define mp  make_pair

bool intersect(auto pair<int,int>&a ,auto pair<int,int>&b){
    int lb = max(a.first , b.first);
    int rb = min(a.second, b.second);
    return (lb <= rb);
}

int main()
{
    int n , l , r;
    ios_base::sync_with_stdio(false);
    cin >> n;
    set<pair<int,int> >have;
    stack<pair<int,int> >del;
    for(int i = 1; i<=n; i++){
        cin >> l >> r;
        auto it = have.upper_bound(mp(r+1,-1));
        if(it==have.begin()){
            have.insert(mp(l,r));
        }
        else{
            it--;
            while(intersect(*it,mp(l,r))){
                del.push(*it);
                r = max(r, it->second);
                l = min(l, it->first);
                if(it == have.begin())
                    break;
                it--;
            }
            while(!del.empty()){
                have.erase(del.top());
                del.pop();
            }
            have.insert(mp(l,r));
        }
        cout << (int)have.size() << " ";
    }
}


///God help me.

#include<bits/stdc++.h>

using namespace std;

#define mp  make_pair

bool intersect(pair<int,int>&a , pair<int,int>&b){
    int lb = max(a.first , b.first);
    int rb = min(a.second, b.second);
    return (lb <= rb);
}

int main()
{
    int n , l , r;
    cin >> n;
    set<pair<int,int> >have;
    stack<pair<int,int> >del;
    for(int i = 1; i<=n; i++){
        cin >> l >> r;
        auto it = have.upper_bound(mp(r+1,-1));
        if(it==have.begin()){
            have.insert(mp(l,r));
        }
        else{
            it--;
            while(intersect(*it,mp(l,r))){
                del.push(*it);
                r = max(r, it->second);
                l = min(l, it->first);
                if(it == have.begin())
                    break;
                it--;
            }
            while(!del.empty()){
                have.erase(del.top());
                del.pop();
            }
            have.insert(mp(l,r));
        }
        cout << (int)have.size() << " ";
    }
}