#include
#define alpha (1.130/2)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int DEM=2;
const int maxn=1000010;
int n,m,now,ans,root,points;
queue<int>Q;
struct point
{
int x[DEM];
bool operator < (const point X) const {return x[now]<X.x[now];}
}one[maxn];
struct node
{
int l,r;
int sze;
int minn[DEM];
int maxx[DEM];
point data;
}tree[maxn];
int dist(point A,point B)
{
int ans=0;
for(int i=0;i<DEM;i++)
ans+=abs(A.x[i]-B.x[i]);
return ans;
}
int get_dist(point A,int pos)
{
int ret=0;
for(int i=0;i<DEM;i++)
ret+=max(0,A.x[i]-tree[pos].maxx[i])+max(0,tree[pos].minn[i]-A.x[i]);
return ret;
}
int New()
{
if(!Q.empty())
{
static int tmp;
tmp=Q.front();
Q.pop();
return tmp;
}
else return ++points;
}
void update(int pos)
{
for(int i=0;i<DEM;i++)
{
tree[pos].maxx[i]=tree[pos].minn[i]=tree[pos].data.x[i];
if(tree[pos].l)
{
tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].l].minn[i]);
tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].l].maxx[i]);
}
if(tree[pos].r)
{
tree[pos].minn[i]=min(tree[pos].minn[i],tree[tree[pos].r].minn[i]);
tree[pos].maxx[i]=max(tree[pos].maxx[i],tree[tree[pos].r].maxx[i]);
}
}
tree[pos].sze=tree[tree[pos].l].sze+tree[tree[pos].r].sze+1;
}
void rev(int pos,int num)
{
if(tree[pos].l) rev(tree[pos].l,num);
one[tree[tree[pos].l].sze+num+1]=tree[pos].data; Q.push(pos);
if(tree[pos].r) rev(tree[pos].r,tree[tree[pos].l].sze+num+1);
}
int build(int l,int r,int dem)
{
if(l>r) return 0;
int mid=(l+r)>>1,pos=New();
now=dem;
nth_element(one+l,one+mid,one+r+1);
tree[pos].data=one[mid];
tree[pos].l=build(l,mid-1,dem^1);
tree[pos].r=build(mid+1,r,dem^1);
update(pos);
return pos;
}
void check(int& pos,int dem)
{
if(tree[pos].sze*alpha<tree[tree[pos].l].sze||tree[pos].sze*alpha<tree[tree[pos].r].sze)
{
rev(pos,0);
pos=build(1,tree[pos].sze,dem);
}
}
int insert(int pos,point data,int dem)
{
if(!pos)
{
pos=New();
tree[pos].l=tree[pos].r=0;
tree[pos].data=data;
update(pos);
return pos;
}
if(data.x[dem]<=tree[pos].data.x[dem]) tree[pos].l=insert(tree[pos].l,data,dem^1);
else tree[pos].r=insert(tree[pos].r,data,dem^1);
update(pos);
check(pos,dem);
return pos;
}
void query(int pos,point data)
{
ans=min(ans,dist(data,tree[pos].data));
int dist_left=INF,dist_right=INF;
if(tree[pos].l) dist_left=get_dist(data,tree[pos].l);
if(tree[pos].r) dist_right=get_dist(data,tree[pos].r);
if(dist_left<dist_right)
{
if(dist_left<ans) query(tree[pos].l,data);
if(dist_right<ans) query(tree[pos].r,data);
}
else
{
if(dist_right<ans) query(tree[pos].r,data);
if(dist_left<ans) query(tree[pos].l,data);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d%d",&one[i].x[0],&one[i].x[1]);
root=build(1,n,0);
int opt,u,v;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&opt,&u,&v);
if(opt==1)
{
root=insert(root,(point){u,v},0);
}
else
{
ans=INF;
query(root,(point){u,v});
printf("%d\n",ans);
}
}
}