#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,1,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=0,f=1;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c==‘-‘) f=-1;
for(;isdigit(c);c=Getchar()) x=x*10+c-‘0‘;
return x*f;
}
const int maxn=100010;
const int maxnode=13000010;
const int inf=1e9;
int n,m,ans,A[maxn],B[maxn],C[maxn],f[maxn];
int root[maxn<<2],maxv[maxnode],ls[maxnode],rs[maxnode],ToT;
void insert(int& o,int l,int r,int p,int val) {
if(!o) o=++ToT;maxv[o]=max(maxv[o],val);
if(l==r) return;int mid=l+r>>1;
if(p<=mid) insert(ls[o],l,mid,p,val);
else insert(rs[o],mid+1,r,p,val);
}
void insert(int o,int l,int r,int x,int y,int val) {
insert(root[o],1,100000,y,val);if(l==r) return;
int mid=l+r>>1,lc=o<<1,rc=lc|1;
if(x<=mid) insert(lc,l,mid,x,y,val);
else insert(rc,mid+1,r,x,y,val);
}
int query(int o,int l,int r,int p) {
if(!o) return 0;
if(l==r) return maxv[o];
int mid=l+r>>1;
if(p<=mid) return query(ls[o],l,mid,p);
return max(maxv[ls[o]],query(rs[o],mid+1,r,p));
}
int query(int o,int l,int r,int x,int y) {
if(l==r) return query(root[o],1,100000,y);
int mid=l+r>>1,lc=o<<1,rc=lc|1;
if(x<=mid) return query(lc,l,mid,x,y);
return max(query(root[lc],1,100000,y),query(rc,mid+1,r,x,y));
}
int main() {
n=read();m=read();
rep(i,1,n) A[i]=B[i]=C[i]=read();
rep(i,1,m) {
int x=read(),y=read();
B[x]=max(B[x],y);
C[x]=min(C[x],y);
}
rep(i,1,n) {
f[i]=query(1,1,100000,A[i],C[i])+1;
insert(1,1,100000,B[i],A[i],f[i]);
ans=max(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}
#include<cstdio>
#include<cctype>
#include<set>
#include<cstring>
#include<algorithm>
#define L T[o].lc
#define R T[o].rc
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
const int BufferSize=1<<16;
char buffer[BufferSize],*head,*tail;
inline char Getchar() {
if(head==tail) {
int l=fread(buffer,1,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read() {
int x=0,f=1;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c==‘-‘) f=-1;
for(;isdigit(c);c=Getchar()) x=x*10+c-‘0‘;
return x*f;
}
const int maxn=100010;
const int inf=1e9;
int D,n,m,ans,A[maxn],B[maxn],C[maxn],f[maxn];
struct Node {
int x[2],mx[2],mn[2],lc,rc,val,maxv;
bool operator < (const Node& ths) const {return x[D]<ths.x[D]||(x[D]==ths.x[D]&&x[D^1]<ths.x[D^1]);}
}T[maxn],P;
void maintain(int o) {T[o].maxv=max(T[o].val,max(T[L].maxv,T[R].maxv));}
void build(int& o,int l,int r,int cur) {
int mid=l+r>>1;D=cur;o=mid;nth_element(T+l,T+mid,T+r+1);
if(l<mid) build(L,l,mid-1,cur^1);
if(mid<r) build(R,mid+1,r,cur^1);
rep(c,0,1) {
T[o].mn[c]=min(T[o].x[c],min(T[L].mn[c],T[R].mn[c]));
T[o].mx[c]=max(T[o].x[c],max(T[L].mx[c],T[R].mx[c]));
}
}
int query(int o) {
if(!o) return 0;
if(T[o].mn[0]>P.x[0]||T[o].mn[1]>P.x[1]) return 0;
if(T[o].mx[0]<=P.x[0]&&T[o].mx[1]<=P.x[1]) return T[o].maxv;
int ans=0;
if(T[o].x[0]<=P.x[0]&&T[o].x[1]<=P.x[1]) ans=T[o].val;
return max(ans,max(query(L),query(R)));
}
void insert(int o,int cur,int val) {
if(T[o].x[0]==P.x[0]&&T[o].x[1]==P.x[1]) T[o].val=max(T[o].val,val);
else {
D=cur;insert(P<T[o]?L:R,cur^1,val);
}
maintain(o);
}
int main() {
T[0].mn[0]=T[0].mn[1]=inf;
T[0].mx[0]=T[0].mx[1]=-inf;
n=read();m=read();int rt=0;
rep(i,1,n) A[i]=B[i]=C[i]=read();
rep(i,1,m) {
int x=read(),y=read();
B[x]=max(B[x],y);
C[x]=min(C[x],y);
}
rep(i,1,n) T[i].x[0]=B[i],T[i].x[1]=A[i];
build(rt,1,n,0);
rep(i,1,n) {
P.x[0]=A[i];P.x[1]=C[i];
f[i]=query(rt)+1;
P.x[0]=B[i];P.x[1]=A[i];
insert(rt,0,f[i]);
ans=max(ans,f[i]);
}
printf("%d\n",ans);
return 0;
}