//In the Name of God

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int n,inf;
int a[550];
int dp[550][550];

int f(int l,int r)
{
  int ret=0;
  while(l<=r)
    if(a[l]==a[r])
      ret++,l++,r--;
    else
      break;
  return ret;
}

int DP(int l,int r)
{
  if(dp[l][r]!=inf)
    return dp[l][r];
  if(l==r)
    return dp[l][r]=1;
  if(l>r)
    return dp[l][r]=0;
  int c=f(l,r),L=r-l+1;
  if(c)
    if(l+c>r-c)
      dp[l][r]=1;
    else
      dp[l][r]=DP(l+c,r-c);
  for(int i=l;i<r;i++)
    dp[l][r]=min(dp[l][r],DP(l,i)+DP(i+1,r));
  return dp[l][r];
}

main()
{
  scanf("%d",&n);
  for(int i=0;i<n;i++)
    scanf("%d",a+i);
  memset(dp,31,sizeof dp);
  inf=dp[0][0];
  cout<<DP(0,n-1)<<endl;
  return 0;
}


//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define fuck whyyouhackme
#define wtf
#define mlgb
#define inf 1000000000
using namespace std;
inline void R(int &v)
{
    v=0;char c=0;int p=1;
    while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
    while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
    v*=p;
}
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline int getint()
{
    int _b=0;char _c;
    for(_c=getchar();_c<'0'||_c>'9';_c=getchar());
    for(;_c>='0'&&_c<='9';_c=getchar())
    {
        _b=(_b<<3)+(_b<<1);
        _b+=_c-'0';
    }
    return _b;
}
inline int exgetint()
{
    int _b=0;char _c;int _p=1;
    for (_c=getchar();(_c<'0'||_c>'9')&&_c!='-';_c=getchar());
    if(_c=='-')
    {
       _c=getchar();
       _p=-1;
    }
    for (;_c>='0'&&_c<='9';_c=getchar())
    {
        _b=(_b<<3)+(_b<<1);
        _b+=_c-'0';
    }
    return _p*_b;
}
inline int Read()
{
    int p=1,x;
    char c;
    while((c=getchar())<'0'||c>'9')
        if(c=='-')
            p=-1;
    x=c-'0';
    while((c=getchar())>'0'&&c<='9')
        x=x*10+c-'0';
    x*=p;
    return x;
}
inline int READ()
{
    char ch;
    bool flag = false;
    int a = 0;
    while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));
    if(ch != '-')
    {
        a *= 10;
        a += ch - '0';
    }
    else
    {
        flag = true;
    }
    while(((ch = getchar()) >= '0') && (ch <= '9'))
    {
        a *= 10;
        a += ch - '0';
    }
    if(flag)
    {
        a = -a;
    }
    return a;
}
void WRITE(int a)
{
    if(a < 0)
    {
        putchar('-');
        a = -a;
    }
    if(a >= 10)
    {
        WRITE(a / 10);
    }
    putchar(a % 10 + '0');
}
template <typename T>
class Treap
{
    #define MAXN 300010
    public:
    int tot;
    int root;
    int ls[MAXN],rs[MAXN],fa[MAXN],priority[MAXN],size[MAXN],num[MAXN];
    T val[MAXN];
    Treap()
    {
        //srand(time(0));
        tot=2;root=1;
        val[1]=inf+1;
        val[2]=-inf-1;
        ls[1]=2;fa[2]=1;
        size[1]=2;size[2]=1;
        priority[1]=priority[2]=inf+1;
        num[1]=num[2]=1;
    }
    int newnode()
    {
        ++tot;
        priority[tot]=rand();
        size[tot]=1;
        num[tot]=1;
        return tot;
    }
    int begin(){return 2;}
    int end(){return 1;}
    int next(int now)
    {
        if(rs[now]!=0)
        {
            int x=rs[now];
            while(ls[x]!=0)x=ls[x];
            return x;
        }
        while(rs[fa[now]]==now)now=fa[now];
        return fa[now];
    }
    int prev(int now)
    {
        if(ls[now]!=0)
        {
            int x=ls[now];
            while(rs[x]!=0)x=rs[x];
            return x;
        }
        while(ls[fa[now]]==now)now=fa[now];
        return fa[now];
    }
    void _dfs(int now)
    {
        if(ls[now]!=0)_dfs(ls[now]);
        cout<<val[now]<<endl;
        if(rs[now]!=0)_dfs(rs[now]);
    }
    void update(int now)
    {
        size[now]=size[ls[now]]+size[rs[now]]+num[now];
    }
    void left_rotate(int now)
    {
        if(now==root)return;
        int f=fa[now],ff=fa[fa[now]],b=ls[now];
        if(f==root)
        {
            root=now;
            ls[now]=f;fa[f]=now;rs[f]=b;
            if(b!=0)fa[b]=f;
        }
        else
        {
            fa[now]=ff;if(ls[ff]==f)ls[ff]=now;else rs[ff]=now;
            ls[now]=f;fa[f]=now;rs[f]=b;
            if(b!=0)fa[b]=f;
        }
        update(f),update(now);
    }
    void right_rotate(int now)
    {
        if(now==root)return;
        int f=fa[now],ff=fa[fa[now]],b=rs[now];
        if(f==root)
        {
            root=now;
            rs[now]=f;fa[f]=now;ls[f]=b;
            if(b!=0)fa[b]=f;
        }
        else
        {
            fa[now]=ff;if(ls[ff]==f)ls[ff]=now;else rs[ff]=now;
            rs[now]=f;fa[f]=now;ls[f]=b;
            if(b!=0)fa[b]=f;
        }
        update(f),update(now);
    }
    void _insert(int now,T x)
    {
        if(x==val[now])
        {
            num[now]++;
            update(now);
            return;
        }
        if(x<val[now])
        {
            if(ls[now]!=0)_insert(ls[now],x);
            else
            {
                ls[now]=newnode();
                fa[tot]=now;
                val[tot]=x;
            }
            if(priority[now]>priority[ls[now]])right_rotate(ls[now]);
        }
        else
        {
            if(rs[now]!=0)_insert(rs[now],x);
            else
            {
                rs[now]=newnode();
                fa[tot]=now;
                val[tot]=x;
            }
            if(priority[now]>priority[rs[now]])left_rotate(rs[now]);
        }
        update(now);
    }
    void down(int now)
    {
        while(ls[now]!=0 || rs[now]!=0)
        {
            if(ls[now]==0)left_rotate(rs[now]);
            else if(rs[now]==0)right_rotate(ls[now]);
            else
            {
                if(priority[ls[now]]<priority[rs[now]])right_rotate(ls[now]);
                else left_rotate(rs[now]);
            }
        }
        int f=fa[now];
        if(ls[f]==now)ls[f]=0;
        if(rs[f]==now)rs[f]=0;
        while(f!=root)update(f),f=fa[f];
    }
    void _erase(int now,T x)
    {
        if(now==0)return;
        if(val[now]==x)
        {
            num[now]--;
            if(num[now]==0)down(now);
            else update(now);
            return;
        }
        if(x<val[now])_erase(ls[now],x);
        else _erase(rs[now],x);
        update(now);
    }
    T _findkth(int now,int kth)
    {
        if(size[ls[now]]>=kth)return _findkth(ls[now],kth);
        int s=kth-size[ls[now]]-num[now];
        if(s<=0)return val[now];
        return _findkth(rs[now],s);
    }
    int _calc(int now,T x)
    {
        if(now==0)return 0;
        if(x<val[now])return _calc(ls[now],x);
        if(x==val[now])return size[ls[now]];
        return  _calc(rs[now],x)+size[ls[now]]+num[now];
    }
    int _find(int now,T x)
    {
        if(now==0)return -1;
        if(x<val[now])
        {
            int ret=_find(ls[now],x);
            if(ret==-1)return prev(now);
            return ret;
        }
        if(x==val[now])return now;
        if(x>val[now])
        {
            int ret=_find(rs[now],x);
            if(ret==-1)return now;
            return ret;
        }
    }
    void insert(T x)
    {
        _insert(root,x);
    }
    void erase(T x)
    {
        _erase(root,x);
    }
    T findkth(int x)
    {
        if(x<0)return -1;
        if(x>size[root]-2)return -1;
        return _findkth(root,x+1);
    }

    int calc(T x)
    {
        return _calc(root,x)-1;
    }
    T findmin(T x)
    {
        int s=_find(root,x);
        if(val[s]==x)s=prev(s);
        if(val[s]<=-inf)return -1;
        return val[s];
    }
    T findmax(T x)
    {
        int s=_find(root,x);
        if(val[s]<=x)s=next(s);
        if(val[s]>=inf)return -1;
        return val[s];
    }
    int find(T x)
    {
        return _find(root,x);
    }
    void sort()
    {
        _dfs(root);
    }
};
int dp[505][505];
int a[505],n;
int update(int sta,int end){
    if(sta==end)return 1;
    if(sta>end)return 0;
    if(a[sta]==a[end])dp[sta][end]=dp[sta+1][end-1];
    if(a[sta]==a[end] && sta==end-1)dp[sta][end]=1;
    dp[sta][end]=min(dp[sta][end],dp[sta+1][end]+1);
    dp[sta][end]=min(dp[sta][end],dp[sta][end-1]+1);
    return dp[sta][end];
}
int main()
{
    cin>>n;memset(dp,63,sizeof dp);
    for(int i=1;i<=n;i++){
        cin>>a[i];
        dp[i][i]=1;
    }

    for(int i=1;i<=n-1;i++){
        for(int j=1;j<=n-i;j++){
            int sta=j,end=i+j;
            update(sta,end);
            for(int k=sta;k<=end-1;k++){
                dp[sta][end]=min(dp[sta][end],update(sta,k)+update(k+1,end));
            }
        }
    }
    cout<<dp[1][n]<<endl;
}


//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define fuck whyyouhackme
#define wtf
#define mlgb
#define inf 1000000000
using namespace std;
inline void R(int &v)
{
    v=0;char c=0;int p=1;
    while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
    while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
    v*=p;
}
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline int getint()
{
    int _b=0;char _c;
    for(_c=getchar();_c<'0'||_c>'9';_c=getchar());
    for(;_c>='0'&&_c<='9';_c=getchar())
    {
        _b=(_b<<3)+(_b<<1);
        _b+=_c-'0';
    }
    return _b;
}
inline int exgetint()
{
    int _b=0;char _c;int _p=1;
    for (_c=getchar();(_c<'0'||_c>'9')&&_c!='-';_c=getchar());
    if(_c=='-')
    {
       _c=getchar();
       _p=-1;
    }
    for (;_c>='0'&&_c<='9';_c=getchar())
    {
        _b=(_b<<3)+(_b<<1);
        _b+=_c-'0';
    }
    return _p*_b;
}
inline int Read()
{
    int p=1,x;
    char c;
    while((c=getchar())<'0'||c>'9')
        if(c=='-')
            p=-1;
    x=c-'0';
    while((c=getchar())>'0'&&c<='9')
        x=x*10+c-'0';
    x*=p;
    return x;
}
inline int READ()
{
    char ch;
    bool flag = false;
    int a = 0;
    while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));
    if(ch != '-')
    {
        a *= 10;
        a += ch - '0';
    }
    else
    {
        flag = true;
    }
    while(((ch = getchar()) >= '0') && (ch <= '9'))
    {
        a *= 10;
        a += ch - '0';
    }
    if(flag)
    {
        a = -a;
    }
    return a;
}
void WRITE(int a)
{
    if(a < 0)
    {
        putchar('-');
        a = -a;
    }
    if(a >= 10)
    {
        WRITE(a / 10);
    }
    putchar(a % 10 + '0');
}
template <typename T>
class Treap
{
    #define MAXN 300010
    public:
    int tot;
    int root;
    int ls[MAXN],rs[MAXN],fa[MAXN],priority[MAXN],size[MAXN],num[MAXN];
    T val[MAXN];
    Treap()
    {
        //srand(time(0));
        tot=2;root=1;
        val[1]=inf+1;
        val[2]=-inf-1;
        ls[1]=2;fa[2]=1;
        size[1]=2;size[2]=1;
        priority[1]=priority[2]=inf+1;
        num[1]=num[2]=1;
    }
    int newnode()
    {
        ++tot;
        priority[tot]=rand();
        size[tot]=1;
        num[tot]=1;
        return tot;
    }
    int begin(){return 2;}
    int end(){return 1;}
    int next(int now)
    {
        if(rs[now]!=0)
        {
            int x=rs[now];
            while(ls[x]!=0)x=ls[x];
            return x;
        }
        while(rs[fa[now]]==now)now=fa[now];
        return fa[now];
    }
    int prev(int now)
    {
        if(ls[now]!=0)
        {
            int x=ls[now];
            while(rs[x]!=0)x=rs[x];
            return x;
        }
        while(ls[fa[now]]==now)now=fa[now];
        return fa[now];
    }
    void _dfs(int now)
    {
        if(ls[now]!=0)_dfs(ls[now]);
        cout<<val[now]<<endl;
        if(rs[now]!=0)_dfs(rs[now]);
    }
    void update(int now)
    {
        size[now]=size[ls[now]]+size[rs[now]]+num[now];
    }
    void left_rotate(int now)
    {
        if(now==root)return;
        int f=fa[now],ff=fa[fa[now]],b=ls[now];
        if(f==root)
        {
            root=now;
            ls[now]=f;fa[f]=now;rs[f]=b;
            if(b!=0)fa[b]=f;
        }
        else
        {
            fa[now]=ff;if(ls[ff]==f)ls[ff]=now;else rs[ff]=now;
            ls[now]=f;fa[f]=now;rs[f]=b;
            if(b!=0)fa[b]=f;
        }
        update(f),update(now);
    }
    void right_rotate(int now)
    {
        if(now==root)return;
        int f=fa[now],ff=fa[fa[now]],b=rs[now];
        if(f==root)
        {
            root=now;
            rs[now]=f;fa[f]=now;ls[f]=b;
            if(b!=0)fa[b]=f;
        }
        else
        {
            fa[now]=ff;if(ls[ff]==f)ls[ff]=now;else rs[ff]=now;
            rs[now]=f;fa[f]=now;ls[f]=b;
            if(b!=0)fa[b]=f;
        }
        update(f),update(now);
    }
    void _insert(int now,T x)
    {
        if(x==val[now])
        {
            num[now]++;
            update(now);
            return;
        }
        if(x<val[now])
        {
            if(ls[now]!=0)_insert(ls[now],x);
            else
            {
                ls[now]=newnode();
                fa[tot]=now;
                val[tot]=x;
            }
            if(priority[now]>priority[ls[now]])right_rotate(ls[now]);
        }
        else
        {
            if(rs[now]!=0)_insert(rs[now],x);
            else
            {
                rs[now]=newnode();
                fa[tot]=now;
                val[tot]=x;
            }
            if(priority[now]>priority[rs[now]])left_rotate(rs[now]);
        }
        update(now);
    }
    void down(int now)
    {
        while(ls[now]!=0 || rs[now]!=0)
        {
            if(ls[now]==0)left_rotate(rs[now]);
            else if(rs[now]==0)right_rotate(ls[now]);
            else
            {
                if(priority[ls[now]]<priority[rs[now]])right_rotate(ls[now]);
                else left_rotate(rs[now]);
            }
        }
        int f=fa[now];
        if(ls[f]==now)ls[f]=0;
        if(rs[f]==now)rs[f]=0;
        while(f!=root)update(f),f=fa[f];
    }
    void _erase(int now,T x)
    {
        if(now==0)return;
        if(val[now]==x)
        {
            num[now]--;
            if(num[now]==0)down(now);
            else update(now);
            return;
        }
        if(x<val[now])_erase(ls[now],x);
        else _erase(rs[now],x);
        update(now);
    }
    T _findkth(int now,int kth)
    {
        if(size[ls[now]]>=kth)return _findkth(ls[now],kth);
        int s=kth-size[ls[now]]-num[now];
        if(s<=0)return val[now];
        return _findkth(rs[now],s);
    }
    int _calc(int now,T x)
    {
        if(now==0)return 0;
        if(x<val[now])return _calc(ls[now],x);
        if(x==val[now])return size[ls[now]];
        return  _calc(rs[now],x)+size[ls[now]]+num[now];
    }
    int _find(int now,T x)
    {
        if(now==0)return -1;
        if(x<val[now])
        {
            int ret=_find(ls[now],x);
            if(ret==-1)return prev(now);
            return ret;
        }
        if(x==val[now])return now;
        if(x>val[now])
        {
            int ret=_find(rs[now],x);
            if(ret==-1)return now;
            return ret;
        }
    }
    void insert(T x)
    {
        _insert(root,x);
    }
    void erase(T x)
    {
        _erase(root,x);
    }
    T findkth(int x)
    {
        if(x<0)return -1;
        if(x>size[root]-2)return -1;
        return _findkth(root,x+1);
    }

    int calc(T x)
    {
        return _calc(root,x)-1;
    }
    T findmin(T x)
    {
        int s=_find(root,x);
        if(val[s]==x)s=prev(s);
        if(val[s]<=-inf)return -1;
        return val[s];
    }
    T findmax(T x)
    {
        int s=_find(root,x);
        if(val[s]<=x)s=next(s);
        if(val[s]>=inf)return -1;
        return val[s];
    }
    int find(T x)
    {
        return _find(root,x);
    }
    void sort()
    {
        _dfs(root);
    }
};
int dp[505][505];
int a[505],n;
int update(int sta,int end){
    if(sta==end)return 1;
    if(sta>end)return 0;
    if(a[sta]==a[end])dp[sta][end]=dp[sta+1][end-1];
    if(a[sta]==a[end] && sta==end-1)dp[sta][end]=1;
    dp[sta][end]=min(dp[sta][end],dp[sta+1][end]+1);
    dp[sta][end]=min(dp[sta][end],dp[sta][end-1]+1);
    return dp[sta][end];
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        dp[i][i]=1;
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            dp[i][j]=inf;
        }
    }
    for(int i=1;i<=n-1;i++){
        for(int j=1;j<=n-i;j++){
            int sta=j,end=i+j;
            update(sta,end);
            for(int k=sta;k<=end-1;k++){
                dp[sta][end]=min(dp[sta][end],update(sta,k)+update(k+1,end));
            }
        }
    }
    cout<<dp[1][n]<<endl;
}


//Copyright(c)2015 liuchenrui
#include<cstdio>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<cstring>
#define fuck whyyouhackme
#define wtf
#define mlgb
#define inf 1000000000
using namespace std;
inline void R(int &v)
{
    v=0;char c=0;int p=1;
    while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();}
    while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();}
    v*=p;
}
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline int getint()
{
    int _b=0;char _c;
    for(_c=getchar();_c<'0'||_c>'9';_c=getchar());
    for(;_c>='0'&&_c<='9';_c=getchar())
    {
        _b=(_b<<3)+(_b<<1);
        _b+=_c-'0';
    }
    return _b;
}
inline int exgetint()
{
    int _b=0;char _c;int _p=1;
    for (_c=getchar();(_c<'0'||_c>'9')&&_c!='-';_c=getchar());
    if(_c=='-')
    {
       _c=getchar();
       _p=-1;
    }
    for (;_c>='0'&&_c<='9';_c=getchar())
    {
        _b=(_b<<3)+(_b<<1);
        _b+=_c-'0';
    }
    return _p*_b;
}
inline int Read()
{
    int p=1,x;
    char c;
    while((c=getchar())<'0'||c>'9')
        if(c=='-')
            p=-1;
    x=c-'0';
    while((c=getchar())>'0'&&c<='9')
        x=x*10+c-'0';
    x*=p;
    return x;
}
inline int READ()
{
    char ch;
    bool flag = false;
    int a = 0;
    while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));
    if(ch != '-')
    {
        a *= 10;
        a += ch - '0';
    }
    else
    {
        flag = true;
    }
    while(((ch = getchar()) >= '0') && (ch <= '9'))
    {
        a *= 10;
        a += ch - '0';
    }
    if(flag)
    {
        a = -a;
    }
    return a;
}
void WRITE(int a)
{
    if(a < 0)
    {
        putchar('-');
        a = -a;
    }
    if(a >= 10)
    {
        WRITE(a / 10);
    }
    putchar(a % 10 + '0');
}
template <typename T>
class Treap
{
    #define MAXN 300010
    public:
    int tot;
    int root;
    int ls[MAXN],rs[MAXN],fa[MAXN],priority[MAXN],size[MAXN],num[MAXN];
    T val[MAXN];
    Treap()
    {
        //srand(time(0));
        tot=2;root=1;
        val[1]=inf+1;
        val[2]=-inf-1;
        ls[1]=2;fa[2]=1;
        size[1]=2;size[2]=1;
        priority[1]=priority[2]=inf+1;
        num[1]=num[2]=1;
    }
    int newnode()
    {
        ++tot;
        priority[tot]=rand();
        size[tot]=1;
        num[tot]=1;
        return tot;
    }
    int begin(){return 2;}
    int end(){return 1;}
    int next(int now)
    {
        if(rs[now]!=0)
        {
            int x=rs[now];
            while(ls[x]!=0)x=ls[x];
            return x;
        }
        while(rs[fa[now]]==now)now=fa[now];
        return fa[now];
    }
    int prev(int now)
    {
        if(ls[now]!=0)
        {
            int x=ls[now];
            while(rs[x]!=0)x=rs[x];
            return x;
        }
        while(ls[fa[now]]==now)now=fa[now];
        return fa[now];
    }
    void _dfs(int now)
    {
        if(ls[now]!=0)_dfs(ls[now]);
        cout<<val[now]<<endl;
        if(rs[now]!=0)_dfs(rs[now]);
    }
    void update(int now)
    {
        size[now]=size[ls[now]]+size[rs[now]]+num[now];
    }
    void left_rotate(int now)
    {
        if(now==root)return;
        int f=fa[now],ff=fa[fa[now]],b=ls[now];
        if(f==root)
        {
            root=now;
            ls[now]=f;fa[f]=now;rs[f]=b;
            if(b!=0)fa[b]=f;
        }
        else
        {
            fa[now]=ff;if(ls[ff]==f)ls[ff]=now;else rs[ff]=now;
            ls[now]=f;fa[f]=now;rs[f]=b;
            if(b!=0)fa[b]=f;
        }
        update(f),update(now);
    }
    void right_rotate(int now)
    {
        if(now==root)return;
        int f=fa[now],ff=fa[fa[now]],b=rs[now];
        if(f==root)
        {
            root=now;
            rs[now]=f;fa[f]=now;ls[f]=b;
            if(b!=0)fa[b]=f;
        }
        else
        {
            fa[now]=ff;if(ls[ff]==f)ls[ff]=now;else rs[ff]=now;
            rs[now]=f;fa[f]=now;ls[f]=b;
            if(b!=0)fa[b]=f;
        }
        update(f),update(now);
    }
    void _insert(int now,T x)
    {
        if(x==val[now])
        {
            num[now]++;
            update(now);
            return;
        }
        if(x<val[now])
        {
            if(ls[now]!=0)_insert(ls[now],x);
            else
            {
                ls[now]=newnode();
                fa[tot]=now;
                val[tot]=x;
            }
            if(priority[now]>priority[ls[now]])right_rotate(ls[now]);
        }
        else
        {
            if(rs[now]!=0)_insert(rs[now],x);
            else
            {
                rs[now]=newnode();
                fa[tot]=now;
                val[tot]=x;
            }
            if(priority[now]>priority[rs[now]])left_rotate(rs[now]);
        }
        update(now);
    }
    void down(int now)
    {
        while(ls[now]!=0 || rs[now]!=0)
        {
            if(ls[now]==0)left_rotate(rs[now]);
            else if(rs[now]==0)right_rotate(ls[now]);
            else
            {
                if(priority[ls[now]]<priority[rs[now]])right_rotate(ls[now]);
                else left_rotate(rs[now]);
            }
        }
        int f=fa[now];
        if(ls[f]==now)ls[f]=0;
        if(rs[f]==now)rs[f]=0;
        while(f!=root)update(f),f=fa[f];
    }
    void _erase(int now,T x)
    {
        if(now==0)return;
        if(val[now]==x)
        {
            num[now]--;
            if(num[now]==0)down(now);
            else update(now);
            return;
        }
        if(x<val[now])_erase(ls[now],x);
        else _erase(rs[now],x);
        update(now);
    }
    T _findkth(int now,int kth)
    {
        if(size[ls[now]]>=kth)return _findkth(ls[now],kth);
        int s=kth-size[ls[now]]-num[now];
        if(s<=0)return val[now];
        return _findkth(rs[now],s);
    }
    int _calc(int now,T x)
    {
        if(now==0)return 0;
        if(x<val[now])return _calc(ls[now],x);
        if(x==val[now])return size[ls[now]];
        return  _calc(rs[now],x)+size[ls[now]]+num[now];
    }
    int _find(int now,T x)
    {
        if(now==0)return -1;
        if(x<val[now])
        {
            int ret=_find(ls[now],x);
            if(ret==-1)return prev(now);
            return ret;
        }
        if(x==val[now])return now;
        if(x>val[now])
        {
            int ret=_find(rs[now],x);
            if(ret==-1)return now;
            return ret;
        }
    }
    void insert(T x)
    {
        _insert(root,x);
    }
    void erase(T x)
    {
        _erase(root,x);
    }
    T findkth(int x)
    {
        if(x<0)return -1;
        if(x>size[root]-2)return -1;
        return _findkth(root,x+1);
    }

    int calc(T x)
    {
        return _calc(root,x)-1;
    }
    T findmin(T x)
    {
        int s=_find(root,x);
        if(val[s]==x)s=prev(s);
        if(val[s]<=-inf)return -1;
        return val[s];
    }
    T findmax(T x)
    {
        int s=_find(root,x);
        if(val[s]<=x)s=next(s);
        if(val[s]>=inf)return -1;
        return val[s];
    }
    int find(T x)
    {
        return _find(root,x);
    }
    void sort()
    {
        _dfs(root);
    }
};
int dp[505][505];
int a[505],n;
int update(int sta,int end){
    if(sta==end)return 1;
    if(sta>end)return 0;
    if(a[sta]==a[end])dp[sta][end]=min(dp[sta][end],dp[sta+1][end-1]);
    if(a[sta]==a[end] && sta==end-1)dp[sta][end]=1;
    dp[sta][end]=min(dp[sta][end],dp[sta+1][end]+1);
    dp[sta][end]=min(dp[sta][end],dp[sta][end-1]+1);
    return dp[sta][end];
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        dp[i][i]=1;
    }
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            dp[i][j]=inf;
        }
    }
    for(int i=1;i<=n-1;i++){
        for(int j=1;j<=n-i;j++){
            int sta=j,end=i+j;
            update(sta,end);
            for(int k=sta;k<=end-1;k++){
                dp[sta][end]=min(dp[sta][end],update(sta,k)+update(k+1,end));
            }
        }
    }
    cout<<dp[1][n]<<endl;
}


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <stack>
#include <map>
#include <vector>
#include <set>
#include <bitset>
#include <string>
#include <queue>
using namespace std;
#define rep(i,l,r) for(i = l; i <= r; i++)
#define red(i,l,r) for(i=(l);i>=(r);i--)
#define u_long unsigned long long
#define fff(i, u) for(i = head[u]; i != -1; i = nxt[i])
#define fin() freopen("in.txt", "r", stdin)
#define fout() freopen("in2.txt", "w", stdout)
#define clr(vis, a) memset(vis, a, sizeof(vis))
#define LL long long
#define ls id << 1
#define rs id << 1 | 1
#define lson id << 1, l, mid
#define rson id << 1 | 1, mid + 1, r
#define mid ( (l + r) >> 1 )
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define X first
#define Y second
#define eps 1e-9
#define pi acos(-1.0)
const int maxn = 500 + 10;
const int maxm = 100 + 10;
const int inf = 1e9;
const int mod = 1e9 + 7;
int getint() {
    char c;
    while((c = getchar()) && !(c >= '0' && c <= '9') && c != '-');
    int ret = c - '0', sgn = 0;
    if(c == '-') sgn = 1, ret = 0;
    while((c = getchar()) && c >= '0' && c <= '9')
        ret = ret * 10 + c - '0';
    if(sgn) ret = -ret;
    return ret;
}
int nxt[maxn][maxm];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int s[maxn];
int last;
int n, p;
int mx, id;
struct ptree{
    int nxt[maxn][maxm];
    int fail[maxn];
    int cnt[maxn];
    int num[maxn];
    int len[maxn];
    int s[maxn];
    int last;
    int n, p, ans;
    int newnode(int l){
        for(int i = 0; i < 26; i ++) nxt[p][i] = 0;
        cnt[p] = num[p] = 0;
        len[p] = l;
        return p ++;
    }
    void init(){
        p = 0;
        newnode(0);
        newnode(-1);
        last = 0;
        n = 0;
        s[n] = -1;
        fail[0] = 1;
        ans = 0;
    }
    int getfail(int x){
        while(s[n - len[x] - 1] != s[n]) x = fail[x];
        return x;
    }
    void add(int ch, int i){
        int c = ch;
        s[++n] = c;
        int cur = getfail(last);
        if(!nxt[cur][c]){
            int now = newnode(len[cur] + 2);
            fail[now] = nxt[getfail(fail[cur])][c];
            nxt[cur][c] = now;
            num[now] = num[fail[now]] + 1;
            ans ++;
        }
        last = nxt[cur][c];
        cnt[last] ++;
        if(len[last] > mx) mx = len[last], id = i;
    }
}pta;
int a[maxn];
int main(){
    n = getint();
    for(int i = 1; i <= n; i ++) a[i] = getint();
    int ans = 0;
    while(1){
        int flag = 0;
        mx = -1;
        pta.init();
        int cnt = 0;
        for(int i = 1; i <= n; i ++) {
            cnt ++;
            flag = 1;
            pta.add(a[i], i);
        }
        if(flag) ans ++;
        else{
            break;
        }
        int l = id - mx, r = id;
        for(int i = r + 1; i <= n; i ++){
            a[++l] = a[i];
        }
        n = l;
    }
    cout << ans << endl;
    return 0;
}


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <stack>
#include <map>
#include <vector>
#include <set>
#include <bitset>
#include <string>
#include <queue>
using namespace std;
#define rep(i,l,r) for(i = l; i <= r; i++)
#define red(i,l,r) for(i=(l);i>=(r);i--)
#define u_long unsigned long long
#define fff(i, u) for(i = head[u]; i != -1; i = nxt[i])
#define fin() freopen("in.txt", "r", stdin)
#define fout() freopen("in2.txt", "w", stdout)
#define clr(vis, a) memset(vis, a, sizeof(vis))
#define LL long long
#define ls id << 1
#define rs id << 1 | 1
#define lson id << 1, l, mid
#define rson id << 1 | 1, mid + 1, r
#define mid ( (l + r) >> 1 )
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define X first
#define Y second
#define eps 1e-9
#define pi acos(-1.0)
const int maxn = 500 + 10;
const int maxm = 100 + 10;
const int inf = 1e9;
const int mod = 1e9 + 7;
int getint() {
    char c;
    while((c = getchar()) && !(c >= '0' && c <= '9') && c != '-');
    int ret = c - '0', sgn = 0;
    if(c == '-') sgn = 1, ret = 0;
    while((c = getchar()) && c >= '0' && c <= '9')
        ret = ret * 10 + c - '0';
    if(sgn) ret = -ret;
    return ret;
}
int nxt[maxn][maxm];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int s[maxn];
int last;
int n, p;
int mx, id;
struct ptree{
    int nxt[maxn][maxm];
    int fail[maxn];
    int cnt[maxn];
    int num[maxn];
    int len[maxn];
    int s[maxn];
    int last;
    int n, p, ans;
    int newnode(int l){
        for(int i = 0; i < 26; i ++) nxt[p][i] = 0;
        cnt[p] = num[p] = 0;
        len[p] = l;
        return p ++;
    }
    void init(){
        p = 0;
        newnode(0);
        newnode(-1);
        last = 0;
        n = 0;
        s[n] = -1;
        fail[0] = 1;
        ans = 0;
    }
    int getfail(int x){
        while(s[n - len[x] - 1] != s[n]) x = fail[x];
        return x;
    }
    void add(int ch, int i){
        int c = ch;
        s[++n] = c;
        int cur = getfail(last);
        if(!nxt[cur][c]){
            int now = newnode(len[cur] + 2);
            fail[now] = nxt[getfail(fail[cur])][c];
            nxt[cur][c] = now;
            num[now] = num[fail[now]] + 1;
            ans ++;
        }
        last = nxt[cur][c];
        cnt[last] ++;
        if(len[last] > mx || len[last] == mx && (len[i - mx + 1] > len[id - mx + 1])) mx = len[last], id = i;
    }
}pta;
int a[maxn];
int main(){
    n = getint();
    for(int i = 1; i <= n; i ++) a[i] = getint();
    int ans = 0;
    while(1){
        int flag = 0;
        mx = -1;
        pta.init();
        int cnt = 0;
        for(int i = 1; i <= n; i ++) {
            cnt ++;
            flag = 1;
            pta.add(a[i], i);
        }
        if(flag) ans ++;
        else{
            break;
        }
        int l = id - mx, r = id;
        for(int i = r + 1; i <= n; i ++){
            a[++l] = a[i];
        }
        n = l;
    }
    cout << ans << endl;
    return 0;
}


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <stack>
#include <map>
#include <vector>
#include <set>
#include <bitset>
#include <string>
#include <queue>
using namespace std;
#define rep(i,l,r) for(i = l; i <= r; i++)
#define red(i,l,r) for(i=(l);i>=(r);i--)
#define u_long unsigned long long
#define fff(i, u) for(i = head[u]; i != -1; i = nxt[i])
#define fin() freopen("in.txt", "r", stdin)
#define fout() freopen("in2.txt", "w", stdout)
#define clr(vis, a) memset(vis, a, sizeof(vis))
#define LL long long
#define ls id << 1
#define rs id << 1 | 1
#define lson id << 1, l, mid
#define rson id << 1 | 1, mid + 1, r
#define mid ( (l + r) >> 1 )
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define X first
#define Y second
#define eps 1e-9
#define pi acos(-1.0)
const int maxn = 500 + 10;
const int maxm = 500 * 500 + 10;
const int inf = 1e9;
const int mod = 1e9 + 7;
int getint() {
    char c;
    while((c = getchar()) && !(c >= '0' && c <= '9') && c != '-');
    int ret = c - '0', sgn = 0;
    if(c == '-') sgn = 1, ret = 0;
    while((c = getchar()) && c >= '0' && c <= '9')
        ret = ret * 10 + c - '0';
    if(sgn) ret = -ret;
    return ret;
}
int nxt[maxn][maxm];
int fail[maxn];
int cnt[maxn];
int num[maxn];
int len[maxn];
int s[maxn];
int last;
int n, p;
int mx, id;
struct ptree{
    int nxt[maxn][maxm];
    int fail[maxn];
    int cnt[maxn];
    int num[maxn];
    int len[maxn];
    int s[maxn];
    int last;
    int n, p, ans;
    int newnode(int l){
        for(int i = 0; i < 26; i ++) nxt[p][i] = 0;
        cnt[p] = num[p] = 0;
        len[p] = l;
        return p ++;
    }
    void init(){
        p = 0;
        newnode(0);
        newnode(-1);
        last = 0;
        n = 0;
        s[n] = -1;
        fail[0] = 1;
        ans = 0;
    }
    int getfail(int x){
        while(s[n - len[x] - 1] != s[n]) x = fail[x];
        return x;
    }
    void add(int ch, int i){
        int c = ch;
        s[++n] = c;
        int cur = getfail(last);
        if(!nxt[cur][c]){
            int now = newnode(len[cur] + 2);
            fail[now] = nxt[getfail(fail[cur])][c];
            nxt[cur][c] = now;
            num[now] = num[fail[now]] + 1;
            ans ++;
        }
        last = nxt[cur][c];
        cnt[last] ++;
        if(len[last] > mx) mx = len[last], id = i;
    }
}pta;
int a[maxn];
int main(){
    n = getint();
    for(int i = 1; i <= n; i ++) a[i] = getint();
    int ans = 0;
    while(1){
        int flag = 0;
        mx = -1;
        pta.init();
        int cnt = 0;
        for(int i = 1; i <= n; i ++) {
            cnt ++;
            flag = 1;
            pta.add(a[i], i);
        }
        if(flag) ans ++;
        else{
            break;
        }
        int l = id - mx, r = id;
        for(int i = r + 1; i <= n; i ++){
            a[++l] = a[i];
        }
        n = l;
    }
    cout << ans << endl;
    return 0;
}


//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <stack>
#include <map>
#include <vector>
#include <set>
#include <bitset>
#include <string>
#include <queue>
using namespace std;
#define rep(i,l,r) for(i = l; i <= r; i++)
#define red(i,l,r) for(i=(l);i>=(r);i--)
#define u_long unsigned long long
#define fff(i, u) for(i = head[u]; i != -1; i = nxt[i])
#define fin() freopen("in.txt", "r", stdin)
#define fout() freopen("in2.txt", "w", stdout)
#define clr(vis, a) memset(vis, a, sizeof(vis))
#define LL long long
#define ls id << 1
#define rs id << 1 | 1
#define lson id << 1, l, mid
#define rson id << 1 | 1, mid + 1, r
#define mid ( (l + r) >> 1 )
#define pb push_back
#define mp make_pair
#define pii pair<int, int>
#define X first
#define Y second
#define eps 1e-9
#define pi acos(-1.0)
const int maxn = 500 + 10;
const int maxm = 500 * 500 + 10;
const int inf = 1e9;
const int mod = 1e9 + 7;
int getint() {
    char c;
    while((c = getchar()) && !(c >= '0' && c <= '9') && c != '-');
    int ret = c - '0', sgn = 0;
    if(c == '-') sgn = 1, ret = 0;
    while((c = getchar()) && c >= '0' && c <= '9')
        ret = ret * 10 + c - '0';
    if(sgn) ret = -ret;
    return ret;
}
int dp[maxn][maxn], a[maxn];
int main(){
    int n = getint();
    for(int i = 1; i <= n; i ++) a[i] = getint();
    for(int i = 1; i <= n; i ++) dp[i][i] = 1;
    for(int len = 2; len <= n; len ++){
        for(int i = 1; i + len - 1 <= n; i ++){
            int j = i + len - 1;
            dp[i][j] = inf;
            for(int k = i; k < j; k ++){
                dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);
            }
            if(a[i] == a[j]) dp[i][j] = min(dp[i][j], max(1, dp[i + 1][j - 1]));
        }
    }
    cout << dp[1][n] << endl;
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#include <stack>
#include <cstdlib>
#include <string>
#include <set>
#include <iostream>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int INF = 1 << 30;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int maxn = 5e2 + 10;
int dp[maxn][maxn][5];
int c[maxn];
vector<int> G[maxn];
bool used[maxn][maxn];

int solve(int l, int r, int x){
    if(used[l][r]){
        return x;
    }
    if(l > r) return 0;
    if(dp[l][r][x]) return dp[l][r][x];
    int ans = INF;
    for(int k = 0; k < G[c[l]].size(); ++ k){
        int i = G[c[l]][k];
        if(i > r) continue;
        if(i < l) break;
        int res = 0;
        res = x + solve(l + 1, i - 1, 0) + solve(i + 1, r, 1);
        ans = min(res, ans);
        if(used[l][i]) break;
    }
    return dp[l][r][x] = ans;
}

int main(){
    int n;
    while(~scanf("%d", &n)){
        memset(used, 0, sizeof(used));
        for(int i = 1; i <= n; ++ i){
            G[i].clear();
        }
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; ++ i){
            scanf("%d", c+i);
        }
        for(int i = n - 1; i >= 0; -- i){
            G[c[i]].push_back(i);
        }

        for(int i = 0; i < n; ++ i){
            int l = i, r = i;
            while(l >= 0 && r < n && c[l] == c[r]){
                used[l][r] = true;
                l --;
                r ++;
            }
        }
        printf("%d\n", solve(0, n - 1, 1));
    }
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#include <stack>
#include <cstdlib>
#include <string>
#include <set>
#include <iostream>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int INF = 1 << 30;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int maxn = 5e2 + 10;
int dp[maxn][maxn][5];
int c[maxn];

int solve(int l, int r, int x){
    if(l > r) return 0;
    if(dp[l][r][x]) return dp[l][r][x];
    int ans = INF;
    for(int i = l; i <= r; ++ i){
        int res = 0;
        if(c[i] == c[l]){
            res = 1 + solve(l + 1, i - 1, 1) + solve(i + 1, r, 0);
            if(x) res --;
            ans = min(res, ans);
        }
    }
    return dp[l][r][x] = ans;
}

int main(){
    int n;
    while(~scanf("%d", &n)){
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; ++ i){
            scanf("%d", c+i);
        }
        printf("%d\n", solve(0, n - 1, 0));
    }
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

using namespace std;
const int INF = 1 << 30;
const int maxn = 5e2 + 5;
int c[maxn];
int dp[maxn][maxn];

int solve(int l, int r){
    if(r < l) return 1;
	if(dp[l][r]) return dp[l][r];
	int min_ = INF;
	if(c[l]==c[r]){
		min_ = min(min_, solve(l+1, r-1));
	}
	for(int i = r-1; i >= l; -- i){
		if(c[l] == c[i]){
			min_ = min(min_, solve(l+1, i-1) + solve(i+1, r));
		}
	}
	return dp[l][r] = min_;
}

int main(){
	int n;
	while(~scanf("%d", &n)){
		memset(dp, 0, sizeof(dp));
		for(int i = 0; i <= n; ++ i){
			for(int j = 0; j <= i; ++ j){
				dp[i][j] = 1;
			}
		}
		for(int i = 0; i < n; ++ i){
			scanf("%d", c+i);
		}
		printf("%d\n", solve(0, n-1));
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#include <stack>
#include <cstdlib>
#include <string>
#include <set>
#include <iostream>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int INF = 1 << 30;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int maxn = 5e2 + 10;
int dp[maxn][maxn][5];
int c[maxn];
vector<int> G[maxn];
bool used[maxn][maxn];

int solve(int l, int r, int x){
    if(used[l][r]){
        return x;
    }
    if(l > r) return 0;
    if(dp[l][r][x]) return dp[l][r][x];
    int ans = INF;
    for(int k = 0; k <= G[c[l]].size(); ++ k){
        int i = G[c[l]][k];
        if(i < l) continue;
        if(i > r) break;
        int res = 0;
        res = x + solve(l + 1, i - 1, 0) + solve(i + 1, r, 1);
        ans = min(res, ans);
    }
    return dp[l][r][x] = ans;
}

int main(){
    int n;
    while(~scanf("%d", &n)){
        memset(used, 0, sizeof(used));
        for(int i = 1; i <= n; ++ i){
            G[i].clear();
        }
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; ++ i){
            scanf("%d", c+i);
            G[c[i]].push_back(i);
        }
        for(int i = 0; i < n; ++ i){
            int l = i, r = i;
            while(l >= 0 && r < n && c[l] == c[r]){
                used[l][r] = true;
                l --;
                r ++;
            }
        }
        printf("%d\n", solve(0, n - 1, 1));
    }
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#include <stack>
#include <cstdlib>
#include <string>
#include <set>
#include <iostream>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int INF = 1 << 30;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int maxn = 5e2 + 10;
int dp[maxn][maxn][5];
int c[maxn];
vector<int> G[maxn];
bool used[maxn][maxn];

int solve(int l, int r, int x){
//    if(used[l][r]){
//        return x;
//    }
    if(l > r) return 0;
    if(dp[l][r][x]) return dp[l][r][x];
    int ans = INF;
    for(int k = 0; k < G[c[l]].size(); ++ k){
        int i = G[c[l]][k];
        if(i > r) continue;
        if(i < l) break;
        int res = 0;
        res = x + solve(l + 1, i - 1, 0) + solve(i + 1, r, 1);
        ans = min(res, ans);
//        if(used[l][i]) break;
    }
    return dp[l][r][x] = ans;
}

int main(){
    int n;
    while(~scanf("%d", &n)){
        memset(used, 0, sizeof(used));
        for(int i = 1; i <= n; ++ i){
            G[i].clear();
        }
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; ++ i){
            scanf("%d", c+i);
        }
        for(int i = n - 1; i >= 0; -- i){
            G[c[i]].push_back(i);
        }
//        for(int i = 0; i < n; ++ i){
//            int l = i, r = i;
//            while(l >= 0 && r < n && c[l] == c[r]){
//                used[l][r] = true;
//                l --;
//                r ++;
//            }
//        }
        printf("%d\n", solve(0, n - 1, 1));
    }
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#include <stack>
#include <cstdlib>
#include <string>
#include <set>
#include <iostream>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
const int INF = 1 << 30;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int maxn = 5e2 + 10;
int dp[maxn][maxn][5];
int c[maxn];
vector<int> G[maxn];
bool used[maxn][maxn];

int solve(int l, int r, int x){
    if(used[l][r]){
        return x;
    }
    if(l > r) return x;
    if(dp[l][r][x]) return dp[l][r][x];
    int ans = INF;
    for(int k = 0; k < G[c[l]].size(); ++ k){
        int i = G[c[l]][k];
        if(i > r) continue;
        if(i < l) break;
        int res = 0;
        res = x + solve(l + 1, i - 1, 0) + solve(i + 1, r, 1);
        ans = min(res, ans);
        if(used[l][i]) break;
    }
    return dp[l][r][x] = ans;
}

int main(){
    int n;
    while(~scanf("%d", &n)){
        memset(used, 0, sizeof(used));
        for(int i = 1; i <= n; ++ i){
            G[i].clear();
        }
        memset(dp, 0, sizeof(dp));
        for(int i = 0; i < n; ++ i){
            scanf("%d", c+i);
        }
        for(int i = n - 1; i >= 0; -- i){
            G[c[i]].push_back(i);
        }
        for(int i = 0; i < n; ++ i){
            int l = i, r = i;
            while(l >= 0 && r < n && c[l] == c[r]){
                used[l][r] = true;
                l --;
                r ++;
            }
        }
        printf("%d\n", solve(0, n - 1, 1));
    }
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 510
int n;
int a[N];
int dp[N][N];
int solve(int l,int  r)
{
    if(l>r)
        return 0;
    if(l==r)
        return dp[l][r] = 1;
    if(dp[l][r]!=-1)
        return dp[l][r];
    dp[l][r]=1+solve(l+1,r);
    for(int i = l+1;i<=r;i++)
    {
        if(a[l]==a[i])
            dp[l][r]=min(dp[l][r],(i-l>1?solve(l+1,i-1):1)+solve(i+1,r));
    }
    return dp[l][r];
}
int main()
{
    int i;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    memset(dp,-1,sizeof(dp));
//    printf("%d\n",solve(2,n-1));
    printf("%d\n",solve(1,n));
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 510
int n;
int a[N];
int dp[N][N];
int solve(int l,int  r)
{
    if(l>r)
        return 0;
    if(l==r)
        return dp[l][r] = 1;
    if(dp[l][r]!=-1)
        return dp[l][r];
    dp[l][r]=1+solve(l+1,r);
    for(int i = l+1;i<=r;i++)
    {
        if(a[l]==a[i])
            dp[l][r]=min(dp[l][r],max(1,i-l>1?solve(l+1,i-1):1+solve(i+1,r)));
    }
    return dp[l][r];
}
int main()
{
    int i;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%d",&a[i]);
    memset(dp,-1,sizeof(dp));
    printf("%d\n",solve(1,n));
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
#define MAX 507
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL)

int arr[MAX];
int dp[MAX][MAX];

int solve(int,int);

int main()
{
    fast_io;
    int n;
    memset(dp,-1,sizeof(dp));
    cin>>n;
    for(int i = 0;i<n;i++)
        cin>>arr[i];
    int maxs = solve(0,n-1);
    cout<<maxs;
    return 0;
}

int solve(int i,int j)
{
    if(i > j)
        return 0;
    if(i == j)
        return 1;
    if( j ==  i+1)
    {
        if(arr[i] == arr[j])
            return 1;
    }
    if(dp[i][j] != -1)
        return dp[i][j];
    int temp = 507;
    if(arr[i] == arr[j])
        temp = min(temp,solve(i+1,j-1));
    for(int k = i;k < j;k++)
            temp = min(temp,solve(i,k) + solve(k+1,j));
    dp[i][j] = temp;
    return temp;
}


#include <bits/stdc++.h>

using namespace std;
#define MAX 507
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL)

int arr[MAX];
int dp[MAX][MAX];

int solve(int,int);

int main()
{
    fast_io;
    int n;
    memset(dp,-1,sizeof(dp));
    cin>>n;
    for(int i = 0;i<n;i++)
        cin>>arr[i];
    int max = solve(0,n-1);
    cout<<max;
    return 0;
}

int solve(int i,int j)
{
    if(i > j)
        return 0;
    if(i == j)
        return 1;
    if( j = i+1)
    {
        if(arr[i] == arr[j])
            return 1;
        else
            return 2;
    }
    if(dp[i][j] != -1)
        return dp[i][j];
    int temp = 507;
    if(arr[i] == arr[j])
        temp = min(temp,solve(i+1,j-1));
    for(int k = i;k < j;k++)
            temp = min(temp,solve(i,k) + solve(k+1,j));
    dp[i][j] = temp;
    return temp;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
#define pfn printf("\n")
#define ll __int64
#define pfd(a) printf("%d\n",a)
#define pf2d(a,b) printf("%d %d\n",a,b)
#define pf3d(a,b,c) printf("%d %d %d\n",a,b,c)
#define pfs(a) printf("%s\n",a)
#define sfd(a) scanf("%d",&a)
#define sf2d(a,b) scanf("%d%d",&a,&b)
#define sf3d(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sfs(a) scanf("%s",a)
#define sf  scanf
#define pf  printf
#define fr(i,n) for(int i=0;i<n;i++)
#define INF 0x7fffffff   //INT_MAX
#define inf 0x3f3f3f3f   //
const double PI = acos(-1.0);
const double e = exp(1.0);
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
template<class T> inline T Min(T a, T b) { return a < b ? a : b; }
template<class T> inline T Max(T a, T b) { return a > b ? a : b; }
bool cmpbig(int a,int b){return a>b;}
bool cmpsmall(int a,int b){return a<b;}
using namespace std;
int num[505];
int dp[505][505];
int main()
{
	//freopen("1.txt","r",stdin);
	int n;
    while(~scanf("%d",&n)){
         for(int i=0;i<n;i++)
        	 scanf("%d",&num[i]);
         //mem(dp);
         int l,r;
         for(int i=0;i<n;i++)
        	 dp[i][i]=1;
         //从0 开始  达到n  ——循环n次，
         //从0-1 1-2 2-3 3-4 ... 0-2 1-3 2-5... 0-n-1
         for(int i=0;i<n;i++)
        	 for(int j=0;j<n-i;j++){ //j<n-j 是保证 r<n
        		 l=j;
        		 r=i+j;
        		 if (l==r)
        			 continue;
        		 dp[l][r]=dp[l+1][r]+1;
        		 for(int k=l+1;k<=r;k++){
        			 if(num[l]==num[k]){
        				  if(k==l+1)
        					  dp[l][r]=min(dp[l][r],1+dp[k+1][r]);
        				  else
        					  dp[l][r]=min(dp[l][r],dp[l+1][k-1]+dp[k+1][r]);
        			 }
        		 }
            }
         printf("%d\n",dp[0][n-1]);
    }
    return 0;
}


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
#define pfn printf("\n")
#define ll __int64
#define pfd(a) printf("%d\n",a)
#define pf2d(a,b) printf("%d %d\n",a,b)
#define pf3d(a,b,c) printf("%d %d %d\n",a,b,c)
#define pfs(a) printf("%s\n",a)
#define sfd(a) scanf("%d",&a)
#define sf2d(a,b) scanf("%d%d",&a,&b)
#define sf3d(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sfs(a) scanf("%s",a)
#define sf  scanf
#define pf  printf
#define fr(i,n) for(int i=0;i<n;i++)
#define INF 0x7fffffff   //INT_MAX
#define inf 0x3f3f3f3f   //
const double PI = acos(-1.0);
const double e = exp(1.0);
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
template<class T> inline T Min(T a, T b) { return a < b ? a : b; }
template<class T> inline T Max(T a, T b) { return a > b ? a : b; }
bool cmpbig(int a,int b){return a>b;}
bool cmpsmall(int a,int b){return a<b;}
using namespace std;
int num[505];
int dp[505][505];
int main()
{
	//freopen("1.txt","r",stdin);
	int n;
    while(~scanf("%d",&n)){
         for(int i=0;i<n;i++)
        	 scanf("%d",&num[i]);
         //mem(dp);
         int l,r;
         for(int i=0;i<n;i++)
        	 dp[i][i]=1;
         //从0 开始  达到n  ——循环n次，
         //从0-1 1-2 2-3 3-4 ... 0-2 1-3 2-5... 0-n-1
         for(int i=0;i<n;i++)
        	 for(int j=0;j<n-i;j++){ //j<n-j 是保证 r<n
        		 l=j;
        		 r=i+j;
        		 if (l==r)
        			 continue;
        		 dp[l][r]=dp[l][r-1]+1;
        		 for(int k=l+1;k<=r;k++){
        			 if(num[l]==num[k]){
        				  if(k==l+1)
        					  dp[l][r]=min(dp[l][r],1+dp[k+1][r]);
        				  else
        					  dp[l][r]=min(dp[l][r],dp[l+1][k-1]+dp[k+1][r]);
        			 }
        		 }
            }
         printf("%d\n",dp[0][n-1]);
    }
    return 0;
}


///green zone start

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <fstream>
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <string>

#define ll long long
#define pb(b) push_back(b)
#define str string
#define sz size()
#define pp pop_back()
#define ld long double
#define endl "\n"
#define mp(a, b) make_pair(a, b)
#define f first
#define s second

///green zone end

using namespace std;
const int inf = int(1e9);
int n, a[1000], d[1000][1000];

///zone for functions start

int calc(int l, int r)
{
	if (l >= r)
		return 1;
	int &res = d[l][r];
	if (res != -1)
		return res;
	res = inf;
	if (a[l] == a[r])
		res = calc(l + 1, r - 1);
	for (int i = l; i <= r; ++i)
		res = min(res, calc(l, i) + calc(i + 1, r));
	return res;
}

///zone for functions end

///code zone

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; ++i)
		cin >> a[i];
	memset(d, -1, sizeof(d));
   	cout << calc(1, n);
}


///green zone start

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <fstream>
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <cstring>

#define ll long long
#define pb(b) push_back(b)
#define str string
#define sz size()
#define pp pop_back()
#define ld long double
#define endl "\n"
#define mp(a, b) make_pair(a, b)
#define f first
#define s second

///green zone end

using namespace std;
const int inf = int(1e9);
int n, a[1000], d[1000][1000];

///zone for functions start

int calc(int l, int r)
{
	if (l >= r)
		return 1;
	int &res = d[l][r];
	if (res != -1)
		return res;
	res = inf;
	if (a[l] == a[r])
		res = calc(l + 1, r - 1);
	for (int i = l; i <= r; ++i)
		res = min(res, calc(l, i) + calc(i + 1, r));
	return res;
}

///zone for functions end

///code zone

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; ++i)
		cin >> a[i];
	memset(d, -1, sizeof(d));
   	cout << calc(1, n);
}


// B. Bear and Displayed Friends
/*
Limak is a little polar bear. He loves connecting with other bears via social networks. He has n friends and his relation with the i-th of them is described by a unique integer t i. The bigger this value is, the better the friendship is. No two friends have the same value t i.

Spring is starting and the Winter sleep is over for bears. Limak has just woken up and logged in. All his friends still sleep and thus none of them is online. Some (maybe all) of them will appear online in the next hours, one at a time.

The system displays friends who are online. On the screen there is space to display at most k friends. If there are more than k friends online then the system displays only k best of them — those with biggest t i.

Your task is to handle queries of two types:

    "1 id" — Friend id becomes online. It's guaranteed that he wasn't online before.
    "2 id" — Check whether friend id is displayed by the system. Print "YES" or "NO" in a separate line.

Are you able to help Limak and answer all queries of the second type?

Input
The first line contains three integers n, k and q (1 ≤ n, q ≤ 150 000, 1 ≤ k ≤ min(6, n)) — the number of friends, the maximum number of displayed online friends and the number of queries, respectively.

The second line contains n integers t 1, t 2, ..., t n (1 ≤ t i ≤ 109) where t i describes how good is Limak's relation with the i-th friend.

The i-th of the following q lines contains two integers type i and id i (1 ≤ type i ≤ 2, 1 ≤ id i ≤ n) — the i-th query. If type i = 1 then a friend id i becomes online. If type i = 2 then you should check whether a friend id i is displayed.

It's guaranteed that no two queries of the first type will have the same id i becuase one friend can't become online twice. Also, it's guaranteed that at least one query will be of the second type ( type i = 2) so the output won't be empty.

Output
For each query of the second type print one line with the answer — "YES" (without quotes) if the given friend is displayed and "NO" (without quotes) otherwise.

Examples
Input
4 2 8
300 950 500 200
1 3
2 4
2 3
1 1
1 2
2 1
2 2
2 3

Output
NO
YES
NO
YES
YES

Input
6 3 9
50 20 51 17 99 24
1 3
1 4
1 5
1 2
2 4
2 2
1 1
2 4
2 3

Output
NO
YES
NO
YES

Note
In the first sample, Limak has 4 friends who all sleep initially. At first, the system displays nobody because nobody is online. There are the following 8 queries:

    "1 3" — Friend 3 becomes online.
    "2 4" — We should check if friend 4 is displayed. He isn't even online and thus we print "NO".
    "2 3" — We should check if friend 3 is displayed. Right now he is the only friend online and the system displays him. We should print "YES".
    "1 1" — Friend 1 becomes online. The system now displays both friend 1 and friend 3.
    "1 2" — Friend 2 becomes online. There are 3 friends online now but we were given k = 2 so only two friends can be displayed. Limak has worse relation with friend 1 than with other two online friends ( t 1 < t 2, t 3) so friend 1 won't be displayed
    "2 1" — Print "NO".
    "2 2" — Print "YES".
    "2 3" — Print "YES".
*/
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	input1, _ := reader.ReadString('\n')
	arr1 := strings.Split(strings.TrimSpace(input1), " ")
	k, _ := strconv.Atoi(arr1[1])
	q, _ := strconv.Atoi(arr1[2])

	input2, _ := reader.ReadString('\n')
	tArr := sToIArr(strings.Split(strings.TrimSpace(input2), " "))

	screen := []int{}
	for i := 0; i < q; i++ {
		input3, _ := reader.ReadString('\n')
		arr2 := strings.Split(strings.TrimSpace(input3), " ")

		typ, _ := strconv.Atoi(arr2[0])
		id, _ := strconv.Atoi(arr2[1])

		if typ == 1 {
			insertScreen(k, id, &screen, tArr)
		} else {
			if findScreen(k, id, &screen, tArr) != -1 {
				fmt.Println("YES")
			} else {
				fmt.Println("NO")
			}
		}
	}
}

func findScreen(k, id int, screen *[]int, tArr []int) int {
	for _, v := range *screen {
		if v == tArr[id-1] {
			return v
		}
	}
	return -1
}

func insertScreen(k, id int, screen *[]int, tArr []int) {
	if len(*screen) >= k {
		if tArr[id-1] > (*screen)[0] {
			(*screen)[0] = tArr[id-1]
		}
	} else {
		(*screen) = append(*screen, tArr[id-1])
		sort.Ints((*screen))
	}
}

func sToIArr(arr []string) (iArr []int) {
	for _, s := range arr {
		i, _ := strconv.Atoi(s)
		iArr = append(iArr, i)
	}
	return
}


// B. Bear and Displayed Friends
/*
Limak is a little polar bear. He loves connecting with other bears via social networks. He has n friends and his relation with the i-th of them is described by a unique integer t i. The bigger this value is, the better the friendship is. No two friends have the same value t i.

Spring is starting and the Winter sleep is over for bears. Limak has just woken up and logged in. All his friends still sleep and thus none of them is online. Some (maybe all) of them will appear online in the next hours, one at a time.

The system displays friends who are online. On the screen there is space to display at most k friends. If there are more than k friends online then the system displays only k best of them — those with biggest t i.

Your task is to handle queries of two types:

    "1 id" — Friend id becomes online. It's guaranteed that he wasn't online before.
    "2 id" — Check whether friend id is displayed by the system. Print "YES" or "NO" in a separate line.

Are you able to help Limak and answer all queries of the second type?

Input
The first line contains three integers n, k and q (1 ≤ n, q ≤ 150 000, 1 ≤ k ≤ min(6, n)) — the number of friends, the maximum number of displayed online friends and the number of queries, respectively.

The second line contains n integers t 1, t 2, ..., t n (1 ≤ t i ≤ 109) where t i describes how good is Limak's relation with the i-th friend.

The i-th of the following q lines contains two integers type i and id i (1 ≤ type i ≤ 2, 1 ≤ id i ≤ n) — the i-th query. If type i = 1 then a friend id i becomes online. If type i = 2 then you should check whether a friend id i is displayed.

It's guaranteed that no two queries of the first type will have the same id i becuase one friend can't become online twice. Also, it's guaranteed that at least one query will be of the second type ( type i = 2) so the output won't be empty.

Output
For each query of the second type print one line with the answer — "YES" (without quotes) if the given friend is displayed and "NO" (without quotes) otherwise.

Examples
Input
4 2 8
300 950 500 200
1 3
2 4
2 3
1 1
1 2
2 1
2 2
2 3

Output
NO
YES
NO
YES
YES

Input
6 3 9
50 20 51 17 99 24
1 3
1 4
1 5
1 2
2 4
2 2
1 1
2 4
2 3

Output
NO
YES
NO
YES

Note
In the first sample, Limak has 4 friends who all sleep initially. At first, the system displays nobody because nobody is online. There are the following 8 queries:

    "1 3" — Friend 3 becomes online.
    "2 4" — We should check if friend 4 is displayed. He isn't even online and thus we print "NO".
    "2 3" — We should check if friend 3 is displayed. Right now he is the only friend online and the system displays him. We should print "YES".
    "1 1" — Friend 1 becomes online. The system now displays both friend 1 and friend 3.
    "1 2" — Friend 2 becomes online. There are 3 friends online now but we were given k = 2 so only two friends can be displayed. Limak has worse relation with friend 1 than with other two online friends ( t 1 < t 2, t 3) so friend 1 won't be displayed
    "2 1" — Print "NO".
    "2 2" — Print "YES".
    "2 3" — Print "YES".
*/
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	input1, _ := reader.ReadString('\n')
	arr1 := strings.Split(strings.TrimSpace(input1), " ")
	k, _ := strconv.Atoi(arr1[1])
	q, _ := strconv.Atoi(arr1[2])

	input2, _ := reader.ReadString('\n')
	tArr := sToIArr(strings.Split(strings.TrimSpace(input2), " "))

	screen := []int{}
	for i := 0; i < q; i++ {
		input3, _ := reader.ReadString('\n')
		arr2 := strings.Split(strings.TrimSpace(input3), " ")

		typ, _ := strconv.Atoi(arr2[0])
		id, _ := strconv.Atoi(arr2[1])

		if typ == 1 {
			insertScreen(k, id, &screen, tArr)
		} else {
			if findScreen(k, id, &screen, tArr) != -1 {
				fmt.Println("YES")
			} else {
				fmt.Println("NO")
			}
		}
	}
}

func findScreen(k, id int, screen *[]int, tArr []int) int {
	for _, v := range *screen {
		if v == tArr[id-1] {
			return v
		}
	}
	return -1
}

func insertScreen(k, id int, screen *[]int, tArr []int) {
	if len(*screen) >= k {
		if tArr[id-1] > (*screen)[0] {
			(*screen)[0] = tArr[id-1]
		}
	} else {
		(*screen) = append(*screen, tArr[id-1])
	}
	sort.Ints((*screen))
}

func sToIArr(arr []string) (iArr []int) {
	for _, s := range arr {
		i, _ := strconv.Atoi(s)
		iArr = append(iArr, i)
	}
	return
}


// B. Bear and Displayed Friends
/*
Limak is a little polar bear. He loves connecting with other bears via social networks. He has n friends and his relation with the i-th of them is described by a unique integer t i. The bigger this value is, the better the friendship is. No two friends have the same value t i.

Spring is starting and the Winter sleep is over for bears. Limak has just woken up and logged in. All his friends still sleep and thus none of them is online. Some (maybe all) of them will appear online in the next hours, one at a time.

The system displays friends who are online. On the screen there is space to display at most k friends. If there are more than k friends online then the system displays only k best of them — those with biggest t i.

Your task is to handle queries of two types:

    "1 id" — Friend id becomes online. It's guaranteed that he wasn't online before.
    "2 id" — Check whether friend id is displayed by the system. Print "YES" or "NO" in a separate line.

Are you able to help Limak and answer all queries of the second type?

Input
The first line contains three integers n, k and q (1 ≤ n, q ≤ 150 000, 1 ≤ k ≤ min(6, n)) — the number of friends, the maximum number of displayed online friends and the number of queries, respectively.

The second line contains n integers t 1, t 2, ..., t n (1 ≤ t i ≤ 109) where t i describes how good is Limak's relation with the i-th friend.

The i-th of the following q lines contains two integers type i and id i (1 ≤ type i ≤ 2, 1 ≤ id i ≤ n) — the i-th query. If type i = 1 then a friend id i becomes online. If type i = 2 then you should check whether a friend id i is displayed.

It's guaranteed that no two queries of the first type will have the same id i becuase one friend can't become online twice. Also, it's guaranteed that at least one query will be of the second type ( type i = 2) so the output won't be empty.

Output
For each query of the second type print one line with the answer — "YES" (without quotes) if the given friend is displayed and "NO" (without quotes) otherwise.

Examples
Input
4 2 8
300 950 500 200
1 3
2 4
2 3
1 1
1 2
2 1
2 2
2 3

Output
NO
YES
NO
YES
YES

Input
6 3 9
50 20 51 17 99 24
1 3
1 4
1 5
1 2
2 4
2 2
1 1
2 4
2 3

Output
NO
YES
NO
YES

Note
In the first sample, Limak has 4 friends who all sleep initially. At first, the system displays nobody because nobody is online. There are the following 8 queries:

    "1 3" — Friend 3 becomes online.
    "2 4" — We should check if friend 4 is displayed. He isn't even online and thus we print "NO".
    "2 3" — We should check if friend 3 is displayed. Right now he is the only friend online and the system displays him. We should print "YES".
    "1 1" — Friend 1 becomes online. The system now displays both friend 1 and friend 3.
    "1 2" — Friend 2 becomes online. There are 3 friends online now but we were given k = 2 so only two friends can be displayed. Limak has worse relation with friend 1 than with other two online friends ( t 1 < t 2, t 3) so friend 1 won't be displayed
    "2 1" — Print "NO".
    "2 2" — Print "YES".
    "2 3" — Print "YES".
*/
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	input1, _ := reader.ReadString('\n')
	arr1 := strings.Split(strings.TrimSpace(input1), " ")
	k, _ := strconv.Atoi(arr1[1])
	q, _ := strconv.Atoi(arr1[2])

	input2, _ := reader.ReadString('\n')
	tArr := sToIArr(strings.Split(strings.TrimSpace(input2), " "))

	screen := []int{}
	for i := 0; i < q; i++ {
		input3, _ := reader.ReadString('\n')
		arr2 := strings.Split(strings.TrimSpace(input3), " ")

		typ, _ := strconv.Atoi(arr2[0])
		id, _ := strconv.Atoi(arr2[1])

		if typ == 1 {
			if len(screen) < k {
				insertScreen(k, id, &screen, tArr)
			} else {
				first := screen[0]
				if tArr[id-1] > first {
					screen[0] = tArr[id-1]
					sort.Ints(screen)
				}
			}
		} else {
			if findScreen(k, id, &screen, tArr) != -1 {
				fmt.Println("YES")
			} else {
				fmt.Println("NO")
			}
		}
	}
}

func findScreen(k, id int, screen *[]int, tArr []int) int {
	for _, v := range *screen {
		if v == tArr[id-1] {
			return v
		}
	}
	return -1
}

func insertScreen(k, id int, screen *[]int, tArr []int) {
	if len(*screen) > k {
		(*screen) = (*screen)[1:]
	} else {
		(*screen) = append(*screen, tArr[id-1])
		sort.Ints((*screen))
	}
}

func sToIArr(arr []string) (iArr []int) {
	for _, s := range arr {
		i, _ := strconv.Atoi(s)
		iArr = append(iArr, i)
	}
	return
}


import random, bisect

class friend(object):
    def __init__(self, ID, t):
        self.ID = ID
        self.t = t
    def __gt__(self, friend2):
        return self.t > friend2.t
    def __repr__(self):
        return "[" + str(self.ID) + ": " + str(self.t) + "]"

n, k, q = (int(n) for n in raw_input().strip().split())
ts = [0] + [int(n) for n in raw_input().strip().split()]

fds = []
for m in xrange(q):
    cmd, f = (int(n) for n in raw_input().strip().split())
    if cmd == 1:
        fd = friend(f, ts[f])
        bisect.insort(fds, fd)
        if len(fds) > k:
            fds.pop(0)
    else:
        for fd in fds:
            if fd.ID == f:
                print "YES"
                break
        else:
            print "NO"


from sys import stdin
from heapq import heappush, heappop

def main():
    nextint = iter(map(int, stdin.read().split())).next
    n, k, q = nextint(), nextint(), nextint()
    friends = [nextint() for _ in xrange(n)]
    top = []
    topset = set()
    out = []
    for _ in xrange(q):
        t, i = nextint(), nextint()
        i -= 1
        if t == 1:
            heappush(top, (friends[i], i))
            topset.add(i)
            if len(top) == k + 1:
                topset.remove(heappop(top)[1])
        else:
            out.append(['NO', 'YES'][i in topset])
    print '\n'.join(out)

main()


n, k, q = map(int, raw_input().split())
scores = [ None ] + list(map(int, raw_input().split()))
top = []
for i in range(q):
  kind, id = map(int, raw_input().split())
  if kind == 1:
    top.append((-scores[id], id))
    top = sorted(top)[:k]
  else:
    found = False
    for _, top_id in top:
      if top_id == id:
        found = True
        break
    print('YES' if found else 'NO')


#
# http://codeforces.com/problemset/problem/658/B
import sys
import heapq

def read_line():
    return next(sys.stdin).strip()

def read_ints():
    return map(int, read_line().split())

N, K, Q = read_ints()
active = [0] * N
scores = read_ints()
heap = []
heapified = False

for i in xrange(Q):
    tag, pk = read_ints()
    pk -= 1

    if tag == 1:
        pair = (scores[pk], pk)
        active[pk] = 1
        if len(heap) < K:
            heap.append(pair)
        else:
            if not heapified:
                heapq.heapify(heap)
                heapified = True
            min_score, min_score_pk = heapq.heappushpop(heap, pair)
            active[min_score_pk] = 0

    if tag == 2:
        print 'YES' if active[pk] else 'NO'


import atexit
import io
import sys

buff = io.BytesIO()
sys.stdout = buff

@atexit.register
def write():
	sys.__stdout__.write(buff.getvalue())

n, k, q = map(int, raw_input().split())
t = map(int, raw_input().split())

l = []
for _ in xrange(q):
	tp, fd = map(int, raw_input().split())
	a = t[fd - 1]
	if tp == 1:
		l.append(a)
		l.sort(reverse=True)
		if len(l) > k:
			l.pop()
	else:
		if a in l:
			print 'YES'
		else:
			print 'NO'


n, k, q = map(int, raw_input().split())
t = map(int, raw_input().split())

l = []
for _ in xrange(q):
	tp, fd = map(int, raw_input().split())
	a = t[fd - 1]
	if tp == 1:
		l.append(a)
		l.sort(reverse=True)
		if len(l) > k:
			l.pop()
	else:
		if a in l:
			print 'YES'
		else:
			print 'NO'


import heapq

n, k, q = map(int, raw_input().split())
t = map(int, raw_input().split())

heap = []
for _ in xrange(q):
	tp, fd = map(int, raw_input().split())
	if tp == 1:
		heapq.heappush(heap, -t[fd - 1])
	else:
		a = -t[fd - 1]
		lt = []
		for _ in xrange(k):
			if not heap:
				print 'NO'
				break
			tmp = heapq.heappop(heap)
			lt.append(tmp)
			if a == tmp:
				print 'YES'
				break
		else:
			print 'NO'
		while lt:
			heapq.heappush(heap, lt.pop())


n,k,q=map(int,raw_input().split())
t=map(int,raw_input().split())
a=[]
for i in range(q):
	ty,si=map(int,raw_input().split())
	if ty==2:
		if si in a:
			print "YES"
		else:
			print "NO"
	else:
		a.append(si)
		if len(a)>k:
			res=10**20
			for j in a:
				res=min(res,t[j-1])
			for j in range(len(a)):
			    if t[a[j]-1]==res:
					del a[j]
					break


n,k,q=map(int,raw_input().split())
N=map(int,raw_input().split())
a=[]
for i in range(q):
	c,d=map(int,raw_input().split())
	if c==2:
		if d in a:
			print "YES"
		else:
			print "NO"
	else:
		if len(a)+1<=k:
			a.append(d)
		else:
			res=10**20
			for i in a:
				if N[i-1]<res:
					res=N[i-1]
					b=i
			a.remove(b)
			a.append(d)


n,k,q=map(int,raw_input().split())
N=map(int,raw_input().split())
a=[]
for i in range(q):
	c,d=map(int,raw_input().split())
	if c==2:
		if d in a:
			print "YES"
		else:
			print "NO"
	else:
		if len(a)+1<=k:
			a.append(d)
		else:
			res=N[d-1]
			for i in a:
				if N[i-1]<res:
					res=N[i-1]
					b=i
			if res!=N[d-1]:
				a.remove(b)
				a.append(d)


from heapq import heappush as offer, heappop as poll

n, k, q = map(int, raw_input().split())
t = map(int, raw_input().split())

display = []
for _ in xrange(q):
    x, y = map(int, raw_input().split())
    if x == 1:
        display.append(t[y-1])
        display.sort(key=lambda x: -x)
    else:

        l, r = 0, min(len(display)-1, k)
        idx = -1
        while l <= r:
            m = (l+r)/2
            if display[m] == t[y-1]:
                idx = m
                break
            elif display[m] < t[y-1]:
                r = m-1
            else:
                l = m+1

        if idx == -1 or idx >= k:
            print "NO"
        else:
            print "YES"


from heapq import heappush as offer, heappop as poll

n, k, q = map(int, raw_input().split())
t = map(int, raw_input().split())

display = []
for _ in xrange(q):
    x, y = map(int, raw_input().split())
    if x == 1:
        display.append(t[y-1])
        display = sorted(display, key=lambda x: -x)[:k]
    else:

        l, r = 0, min(len(display)-1, k)
        idx = -1
        while l <= r:
            m = (l+r)/2
            if display[m] == t[y-1]:
                idx = m
                break
            elif display[m] < t[y-1]:
                r = m-1
            else:
                l = m+1

        if idx == -1 or idx >= k:
            print "NO"
        else:
            print "YES"


N, K, Q = raw_input().strip().split(' ')
N, K, Q = int(N), int(K), int(Q)

Online = []
Len = 0
T = raw_input().strip().split(' ')
for i in xrange(N): T[i] = int(T[i])

for i in xrange(Q):
    Type, ID = raw_input().strip().split(' ')
    ID = int(ID)

    if Type == '2':
        Flag = False
        for User in Online:
            if ID == User[1]:
                Flag = True
                break
        if Flag == True: print "YES"
        else: print "NO"

    else:
        if Len < K:
            Online.append([T[ID-1], ID])
            Len += 1
        else:
            MIN_I = -1
            MIN_T = 10000000001
            for j in xrange(Len):
                if Online[j][0] < MIN_T:
                    MIN_I = j
                    MIN_T = Online[j][0]

            if MIN_T < T[ID-1]:
                del Online[MIN_I]
                Online.append([T[ID-1], ID])


from heapq import *

"""
[int(i) for i in raw_input().split(" ")]
raw_input()
raw_input().split(" ")

"""

def main():
	n,k,q = [int(i) for i in raw_input().split(" ")]
	Fr = [0]
	Fr.extend([int(i) for i in raw_input().split(" ")])

	res = []

	hp = []
	friends = set()

	for i in range(q):
		t,n = [int(i) for i in raw_input().split(" ")]
		if t == 1:

			heappush(hp, (Fr[n],n) )
			friends.add(n)

			if len(hp) > k:
				_rank, n_rem = heappop(hp)
				friends.remove(n_rem)

		if t == 2:
			if n in friends:
				res.append("YES")
			else:
				res.append("NO")

	print "\n".join(res)

main()


rr=raw_input
rrI = lambda: int(rr())
rrM = lambda: map(int,rr().split())
debug=0
if debug:
    fi = open('t.txt','r')
    rr=lambda: fi.readline().replace('\n','')

N,K,Q = rrM()
S = rrM()

global MINCACHE,CACHE
CACHE = [(0,0)]*K
MINCACHE = 0

def inser(Qid):
    global CACHE,MINCACHE
    targ = S[Qid-1]
    if targ > MINCACHE:
        CACHE.append((targ,Qid))
        CACHE.sort(reverse=True)
        CACHE = CACHE[:K]
        MINCACHE = min(MINCACHE, targ)
def check(Qid):
    global CACHE
    for i,j in CACHE:
        if j==Qid:
            print "YES"
            break
    else:
        print "NO"

for q in xrange(Q):
    Qtype,Qid = rrM()
    if Qtype == 1: #Someone became online
        inser(Qid)
    else: #Check whether Qid is represented
        check(Qid)


from operator import itemgetter

class CodeforcesTask658BSolution:
    def __init__(self):
        self.result = ''
        self.n_k_q = []
        self.rels = []
        self.queries = []

    def read_input(self):
        self.n_k_q = [int(x) for x in input().split(" ")]
        self.rels = [int(x) for x in input().split(" ")]
        for x in range(self.n_k_q[2]):
            self.queries.append([int(y) for y in input().split(" ")])

    def process_task(self):
        online = []
        results = []
        shown = {}
        for query in self.queries:
            if query[0] == 1:
                shown[query[1]] = True
                online.append((query[1], self.rels[query[1] - 1]))
                online.sort(key=itemgetter(1), reverse=True)
                if len(online) > self.n_k_q[1]:
                    out = online.pop(-1)
                    shown[out[0]] = False
            else:
                if query[1] in shown:
                    if shown[query[1]]:
                        results.append("YES")
                    else:
                        results.append("NO")
                else:
                    results.append("NO")
        self.result = "\n".join(results)

    def get_result(self):
        return self.result

if __name__ == "__main__":
    Solution = CodeforcesTask658BSolution()
    Solution.read_input()
    Solution.process_task()
    print(Solution.get_result())


import sys
import math
import itertools as it
import operator as op
import heapq

n, k, q = map(int, sys.stdin.readline().split())
T = list(map(int, sys.stdin.readline().split()))

online = []
for i in range(q):
  t, fid = map(int, sys.stdin.readline().split())
  fid -= 1
  if t == 1:
    heapq.heappush(online, (-T[fid], fid))
    online = heapq.nsmallest(k, online)
  else:
    if (-T[fid], fid) in online:
      print('YES')
    else:
      print('NO')


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
	internal class Template
	{
		private void Solve()
		{
			var n = cin.NextInt();
			var k = cin.NextInt();
			var q = cin.NextInt();

			var t = new int[n];
			for (var i = 0; i < t.Length; i++)
			{
				t[i] = cin.NextInt();
			}

			var queue = new List<Friend>();

			var ok = new bool[n];

			var sb = new StringBuilder();
			for (var i = 0; i < q; i++)
			{
				var type = cin.NextInt();
				var id = cin.NextInt();
				if (type == 1)
				{
					var friend = new Friend { Id = id, T = t[id - 1] };
					if (queue.Count < k)
					{
						queue.Add(friend);
						ok[id - 1] = true;
					}
					else
					{
						var minIdx = 0;
						var minValue = queue[0].T;
						for (var j = 1; j < queue.Count; j++)
						{
							if (queue[j].T < minValue)
							{
								minIdx = j;
								minValue = queue[j].T;
							}
						}

						if (minValue < friend.T)
						{
							ok[queue[minIdx].Id - 1] = false;
							ok[friend.Id - 1] = true;
							queue[minIdx] = friend;
						}
					}
				}
				else
				{
					var result = ok[id - 1] ? "YES" : "NO";
					sb.AppendLine(result);
				}
			}
			var output = sb.ToString();
			Console.WriteLine(output);
		}

		public struct Friend
		{
			public int Id;
			public int T;
		}

		private static readonly Scanner cin = new Scanner();

		private static void Main()
		{
			new Template().Solve();
			Console.ReadLine();
		}
	}

	internal class Scanner
	{
		private string[] s = new string[0];
		private int i;
		private readonly char[] cs = { ' ' };

		public string NextString()
		{
			if (i < s.Length) return s[i++];
			var line = Console.ReadLine() ?? string.Empty;
			s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			i = 1;
			return s.First();
		}

		public double NextDouble()
		{
			return double.Parse(NextString());
		}

		public int NextInt()
		{
			return int.Parse(NextString());
		}

		public long NextLong()
		{
			return long.Parse(NextString());
		}
	}
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
	internal class Template
	{
		private void Solve()
		{
			var n = cin.NextInt();
			var k = cin.NextInt();
			var q = cin.NextInt();

			var t = new int[n];
			for (var i = 0; i < t.Length; i++)
			{
				t[i] = cin.NextInt();
			}

			var queue = new List<Friend>();

			var sb = new StringBuilder();
			for (var i = 0; i < q; i++)
			{
				var type = cin.NextInt();
				var id = cin.NextInt();
				if (type == 1)
				{
					var friend = new Friend { Id = id, T = t[id - 1] };
					if (queue.Count < k)
					{
						queue.Add(friend);
					}
					else
					{
						var minIdx = 0;
						var minValue = queue[0].T;
						for (var j = 1; j < queue.Count; j++)
						{
							if (queue[j].T < minValue)
							{
								minIdx = j;
								minValue = queue[j].T;
							}
						}

						if (minValue < friend.T)
						{
							queue[minIdx] = friend;
						}
					}
				}
				else
				{
					var result = queue.Any(x => x.Id == id) ? "YES" : "NO";
					sb.AppendLine(result);
				}
			}
			var output = sb.ToString();
			Console.WriteLine(output);
		}

		public struct Friend
		{
			public int Id;
			public int T;
		}

		private static readonly Scanner cin = new Scanner();

		private static void Main()
		{
			new Template().Solve();
			Console.ReadLine();
		}
	}

	internal class Scanner
	{
		private string[] s = new string[0];
		private int i;
		private readonly char[] cs = { ' ' };

		public string NextString()
		{
			if (i < s.Length) return s[i++];
			var line = Console.ReadLine() ?? string.Empty;
			s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			i = 1;
			return s.First();
		}

		public double NextDouble()
		{
			return double.Parse(NextString());
		}

		public int NextInt()
		{
			return int.Parse(NextString());
		}

		public long NextLong()
		{
			return long.Parse(NextString());
		}
	}
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
    internal class Template
    {
        private void Solve()
        {
            var n = cin.NextInt();
            var k = cin.NextInt();
            var q = cin.NextInt();

            var t = new int[n];
            for (var i = 0; i < t.Length; i++)
            {
                t[i] = cin.NextInt();
            }

            var queue = new PriorityQueue<Friend, Friend>(new FriendComparer());

            var ok = new bool[n];

            var sb = new StringBuilder();
            for (var i = 0; i < q; i++)
            {
                var type = cin.NextInt();
                var id = cin.NextInt();
                if (type == 1)
                {
                    var friend = new Friend {Id = id, T = t[id - 1]};
                    if (queue.Count < k)
                    {
                        queue.Enqueue(friend, friend);
                        ok[id - 1] = true;
                    }
                    else
                    {
                        var top = queue.PeekValue();
                        if (top.T < friend.T)
                        {
                            queue.Dequeue();
                            ok[top.Id - 1] = false;
                            queue.Enqueue(friend, friend);
                            ok[friend.Id - 1] = true;
                        }
                    }
                }
                else
                {
                    var result = ok[id - 1] ? "YES" : "NO";
                    sb.AppendLine(result);
                }
            }
            var output = sb.ToString();
            Console.WriteLine(output);
        }

        public struct Friend
        {
            public int Id;
            public int T;
        }

        public class FriendComparer : IComparer<Friend>
        {
            public int Compare(Friend x, Friend y)
            {
                return x.T.CompareTo(y.T);
            }
        }

        public class PriorityQueue<TPriority, TValue> : ICollection<KeyValuePair<TPriority, TValue>>
        {
            private readonly List<KeyValuePair<TPriority, TValue>> baseHeap;
            private readonly IComparer<TPriority> comparer;

            public PriorityQueue()
                : this(Comparer<TPriority>.Default)
            {
            }

            public PriorityQueue(int capacity)
                : this(capacity, Comparer<TPriority>.Default)
            {
            }

            public PriorityQueue(int capacity, IComparer<TPriority> comparer)
            {
                if (comparer == null)
                    throw new ArgumentNullException();

                baseHeap = new List<KeyValuePair<TPriority, TValue>>(capacity);
                this.comparer = comparer;
            }

            public PriorityQueue(IComparer<TPriority> comparer)
            {
                if (comparer == null)
                    throw new ArgumentNullException();

                baseHeap = new List<KeyValuePair<TPriority, TValue>>();
                this.comparer = comparer;
            }

            public PriorityQueue(IEnumerable<KeyValuePair<TPriority, TValue>> data)
                : this(data, Comparer<TPriority>.Default)
            {
            }

            public PriorityQueue(IEnumerable<KeyValuePair<TPriority, TValue>> data, IComparer<TPriority> comparer)
            {
                if (data == null || comparer == null)
                    throw new ArgumentNullException();

                this.comparer = comparer;
                baseHeap = new List<KeyValuePair<TPriority, TValue>>(data);
                // heapify data
                for (int pos = baseHeap.Count / 2 - 1; pos >= 0; pos--)
                    HeapifyFromBeginningToEnd(pos);
            }

            public static PriorityQueue<TPriority, TValue> MergeQueues(PriorityQueue<TPriority, TValue> pq1, PriorityQueue<TPriority, TValue> pq2)
            {
                if (pq1 == null || pq2 == null)
                    throw new ArgumentNullException();
                // ReSharper disable once PossibleUnintendedReferenceComparison
                if (pq1.comparer != pq2.comparer)
                    throw new InvalidOperationException("Priority queues to be merged must have equal comparers");
                return MergeQueues(pq1, pq2, pq1.comparer);
            }

            public static PriorityQueue<TPriority, TValue> MergeQueues(PriorityQueue<TPriority, TValue> pq1, PriorityQueue<TPriority, TValue> pq2, IComparer<TPriority> comparer)
            {
                if (pq1 == null || pq2 == null || comparer == null)
                    throw new ArgumentNullException();
                // merge data
                PriorityQueue<TPriority, TValue> result = new PriorityQueue<TPriority, TValue>(pq1.Count + pq2.Count, pq1.comparer);
                result.baseHeap.AddRange(pq1.baseHeap);
                result.baseHeap.AddRange(pq2.baseHeap);
                // heapify data
                for (int pos = result.baseHeap.Count / 2 - 1; pos >= 0; pos--)
                    result.HeapifyFromBeginningToEnd(pos);

                return result;
            }

            public void Enqueue(TPriority priority, TValue value)
            {
                Insert(priority, value);
            }

            public KeyValuePair<TPriority, TValue> Dequeue()
            {
                if (!IsEmpty)
                {
                    KeyValuePair<TPriority, TValue> result = baseHeap[0];
                    DeleteRoot();
                    return result;
                }
                else
                    throw new InvalidOperationException("Priority queue is empty");
            }

            public TValue DequeueValue()
            {
                return Dequeue().Value;
            }

            public KeyValuePair<TPriority, TValue> Peek()
            {
                if (!IsEmpty)
                    return baseHeap[0];
                else
                    throw new InvalidOperationException("Priority queue is empty");
            }

            public TValue PeekValue()
            {
                return Peek().Value;
            }

            public bool IsEmpty
            {
                get { return baseHeap.Count == 0; }
            }

            private void ExchangeElements(int pos1, int pos2)
            {
                KeyValuePair<TPriority, TValue> val = baseHeap[pos1];
                baseHeap[pos1] = baseHeap[pos2];
                baseHeap[pos2] = val;
            }

            private void Insert(TPriority priority, TValue value)
            {
                KeyValuePair<TPriority, TValue> val = new KeyValuePair<TPriority, TValue>(priority, value);
                baseHeap.Add(val);

                // heap[i] have children heap[2*i + 1] and heap[2*i + 2] and parent heap[(i-1)/ 2];

                // heapify after insert, from end to beginning
                HeapifyFromEndToBeginning(baseHeap.Count - 1);
            }

            private int HeapifyFromEndToBeginning(int pos)
            {
                if (pos >= baseHeap.Count) return -1;

                while (pos > 0)
                {
                    int parentPos = (pos - 1) / 2;
                    if (comparer.Compare(baseHeap[parentPos].Key, baseHeap[pos].Key) > 0)
                    {
                        ExchangeElements(parentPos, pos);
                        pos = parentPos;
                    }
                    else break;
                }
                return pos;
            }

            private void DeleteRoot()
            {
                if (baseHeap.Count <= 1)
                {
                    baseHeap.Clear();
                    return;
                }

                baseHeap[0] = baseHeap[baseHeap.Count - 1];
                baseHeap.RemoveAt(baseHeap.Count - 1);

                // heapify
                HeapifyFromBeginningToEnd(0);
            }

            private void HeapifyFromBeginningToEnd(int pos)
            {
                if (pos >= baseHeap.Count) return;

                // heap[i] have children heap[2*i + 1] and heap[2*i + 2] and parent heap[(i-1)/ 2];

                while (true)
                {
                    // on each iteration exchange element with its smallest child
                    int smallest = pos;
                    int left = 2 * pos + 1;
                    int right = 2 * pos + 2;
                    if (left < baseHeap.Count && comparer.Compare(baseHeap[smallest].Key, baseHeap[left].Key) > 0)
                        smallest = left;
                    if (right < baseHeap.Count && comparer.Compare(baseHeap[smallest].Key, baseHeap[right].Key) > 0)
                        smallest = right;

                    if (smallest != pos)
                    {
                        ExchangeElements(smallest, pos);
                        pos = smallest;
                    }
                    else break;
                }
            }

            public void Add(KeyValuePair<TPriority, TValue> item)
            {
                Enqueue(item.Key, item.Value);
            }

            public void Clear()
            {
                baseHeap.Clear();
            }

            public bool Contains(KeyValuePair<TPriority, TValue> item)
            {
                return baseHeap.Contains(item);
            }

            public int Count
            {
                get { return baseHeap.Count; }
            }

            public void CopyTo(KeyValuePair<TPriority, TValue>[] array, int arrayIndex)
            {
                baseHeap.CopyTo(array, arrayIndex);
            }

            public bool IsReadOnly
            {
                get { return false; }
            }

            public bool Remove(KeyValuePair<TPriority, TValue> item)
            {
                // find element in the collection and remove it
                int elementIdx = baseHeap.IndexOf(item);
                if (elementIdx < 0) return false;

                //remove element
                baseHeap[elementIdx] = baseHeap[baseHeap.Count - 1];
                baseHeap.RemoveAt(baseHeap.Count - 1);

                // heapify
                int newPos = HeapifyFromEndToBeginning(elementIdx);
                if (newPos == elementIdx)
                    HeapifyFromBeginningToEnd(elementIdx);

                return true;
            }

            public IEnumerator<KeyValuePair<TPriority, TValue>> GetEnumerator()
            {
                return baseHeap.GetEnumerator();
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
        }

        private static readonly Scanner cin = new Scanner();

        private static void Main()
        {
#if DEBUG
            var inputText = File.ReadAllText(@"..\..\input.txt");
            var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
            var consoleOut = Console.Out;
            for (var i = 0; i < testCases.Length; i++)
            {
                var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
                Console.SetIn(new StringReader(parts[0].Trim()));
                var stringWriter = new StringWriter();
                Console.SetOut(stringWriter);
                var sw = Stopwatch.StartNew();
                new Template().Solve();
                sw.Stop();
                var output = stringWriter.ToString();

                Console.SetOut(consoleOut);
                var color = ConsoleColor.Green;
                var status = "Passed";
                if (parts[1].Trim() != output.Trim())
                {
                    color = ConsoleColor.Red;
                    status = "Failed";
                }
                Console.ForegroundColor = color;
                Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
            }
            Console.ReadLine();
            Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
        }
    }

    internal class Scanner
    {
        private string[] s = new string[0];
        private int i;
        private readonly char[] cs = { ' ' };

        public string NextString()
        {
            if (i < s.Length) return s[i++];
            var line = Console.ReadLine() ?? string.Empty;
            s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 1;
            return s.First();
        }

        public double NextDouble()
        {
            return double.Parse(NextString());
        }

        public int NextInt()
        {
            return int.Parse(NextString());
        }

        public long NextLong()
        {
            return long.Parse(NextString());
        }
    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Codeforces
{
	internal class Template
	{
		private void Solve()
		{
			var n = cin.NextInt();
			var k = cin.NextInt();
			var q = cin.NextInt();

			var t = new int[n];
			for (var i = 0; i < t.Length; i++)
			{
				t[i] = cin.NextInt();
			}

			var queue = new List<Friend>();

			var ok = new bool[n];

			var sb = new StringBuilder();
			for (var i = 0; i < q; i++)
			{
				var type = cin.NextInt();
				var id = cin.NextInt();
				if (type == 1)
				{
					var friend = new Friend { Id = id, T = t[id - 1] };
					if (queue.Count < k)
					{
						queue.Add(friend);
						ok[id - 1] = true;
					}
					else
					{
						var minIdx = 0;
						var minValue = queue[0].T;
						for (var j = 1; j < queue.Count; j++)
						{
							if (queue[i].T < minValue)
							{
								minIdx = i;
								minValue = queue[i].T;
							}
						}

						if (minValue < friend.T)
						{
							ok[queue[minIdx].Id - 1] = false;
							ok[friend.Id - 1] = true;
							queue[minIdx] = friend;
						}
					}
				}
				else
				{
					var result = ok[id - 1] ? "YES" : "NO";
					sb.AppendLine(result);
				}
			}
			var output = sb.ToString();
			Console.WriteLine(output);
		}

		public struct Friend
		{
			public int Id;
			public int T;
		}

		public class FriendComparer : IComparer<Friend>
		{
			public int Compare(Friend x, Friend y)
			{
				return x.T.CompareTo(y.T);
			}
		}

		private static readonly Scanner cin = new Scanner();

		private static void Main()
		{
#if DEBUG
			var inputText = File.ReadAllText(@"..\..\input.txt");
			var testCases = inputText.Split(new[] { "input" }, StringSplitOptions.RemoveEmptyEntries);
			var consoleOut = Console.Out;
			for (var i = 0; i < testCases.Length; i++)
			{
				var parts = testCases[i].Split(new[] { "output" }, StringSplitOptions.RemoveEmptyEntries);
				Console.SetIn(new StringReader(parts[0].Trim()));
				var stringWriter = new StringWriter();
				Console.SetOut(stringWriter);
				var sw = Stopwatch.StartNew();
				new Template().Solve();
				sw.Stop();
				var output = stringWriter.ToString();

				Console.SetOut(consoleOut);
				var color = ConsoleColor.Green;
				var status = "Passed";
				if (parts[1].Trim() != output.Trim())
				{
					color = ConsoleColor.Red;
					status = "Failed";
				}
				Console.ForegroundColor = color;
				Console.WriteLine("Test {0} {1} in {2}ms", i + 1, status, sw.ElapsedMilliseconds);
			}
			Console.ReadLine();
			Console.ReadKey();
#else
			new Template().Solve();
			Console.ReadLine();
#endif
		}
	}

	internal class Scanner
	{
		private string[] s = new string[0];
		private int i;
		private readonly char[] cs = { ' ' };

		public string NextString()
		{
			if (i < s.Length) return s[i++];
			var line = Console.ReadLine() ?? string.Empty;
			s = line.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			i = 1;
			return s.First();
		}

		public double NextDouble()
		{
			return double.Parse(NextString());
		}

		public int NextInt()
		{
			return int.Parse(NextString());
		}

		public long NextLong()
		{
			return long.Parse(NextString());
		}
	}
}


using System;
using System.Linq;

namespace prob1
{
    class Program
    {
        static void Main()
        {
            string[] input = Console.ReadLine().Split();
            int n = int.Parse(input[0]);
            int k = int.Parse(input[1]);
            int q = int.Parse(input[2]);

            input = Console.ReadLine().Split();
            int[] friendships = new int[n];
            for(int i = 0; i < n; i++)
            {
                friendships[i] = int.Parse(input[i]);
            }

            int[] shown = new int[k];
            bool[] online = new bool[n];
            for(int i = 0; i < k; i++) shown[i] = -1;

            for(int i = 0; i < q; i++)
            {
                input = Console.ReadLine().Split();
                int query = int.Parse(input[0]);
                int friend = int.Parse(input[1]) - 1;
                if(query == 1)
                {
                    online[friend] = true;
                    bool passToNext = false;
                    for(int j = 0; j < shown.Length; j++)
                    {
                        if(shown[j] == -1)
                        {
                            shown[j] = friend; passToNext = true; break;
                        }
                    }
                    if(passToNext) continue;
                    int minFriendship = int.MaxValue;
                    //int minFriend = 0;
                    int minFriendIndex = 0;
                    for(int h = 0; h < k; h++)
                    {
                        if(minFriendship > friendships[shown[h]])
                        {
                            minFriendship = friendships[shown[h]];
                            //minFriend = shown[h];
                            minFriendIndex = h;
                        }
                    }
                    if(minFriendship < friendships[friend])
                    {
                        shown[minFriendIndex] = friend;
                    }
                }
                else
                {
                    //if(online[friend] == false) Console.WriteLine("NO");
                    //else
                    //{
                        if(shown.Contains(friend)) Console.WriteLine("YES");
                        else Console.WriteLine("NO");
                    //}
                }
            }
        }
    }
}