/*
结点i的左儿子是2i,右儿子是2i+1
那么显然这是一棵完全二叉树。
由于没有很好直接查询的办法,所以先考虑预处理一下这棵树
根据完全二叉树的性质,sum{size[i]}<=nlogn,所以直接用vector存下结点的所有孩子,自底向上对到子树距离归并排序
这样预处理完后,对于每个询问(A,H),我们只要以A为起点不断向上爬(最多logn次),通过lower_bound来计算贡献
*/
#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define N 1000005
#define ll long long
struct Edge{
ll to,nxt,w;
}e[N<<1];
int head[N],tot;
void init(){
memset(head,-1,sizeof head);
tot=0;
}
void add(int u,int v,ll w){
e[tot].to=v;e[tot].w=w;e[tot].nxt=head[u];head[u]=tot++;
}
vector<ll>dis[N];
int n,m;
vector<ll> merge(vector<ll> & fa, vector<ll> & son,ll w){
vector<ll>res;res.clear();
int p1=0,p2=0;
while(1){
if(fa[p1]<=son[p2]+w){
res.push_back(fa[p1]);
++p1;
}
else {
res.push_back(son[p2]+w);
++p2;
}
if(p1==fa.size() || p2==son.size())break;
}
while(p1<fa.size())
res.push_back(fa[p1]),p1++;
while(p2<son.size())
res.push_back(son[p2]+w),p2++;
return res;
}
void dfs(int u,int pre){
int son=0;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(v==pre)continue;
son++;dfs(v,u);
}
dis[u].push_back(0);
if(son==0)return;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(v==pre)continue;
dis[u]=merge(dis[u],dis[v],e[i].w);
}
}
vector<ll>sum[N];
void sumup(){
for(int i=1;i<=n;i++)sum[i]=dis[i];
for(int i=1;i<=n;i++){
for(int j=1;j<sum[i].size();j++)
sum[i][j]+=sum[i][j-1];
}
}
ll W[N];
ll query(int u,ll H){//在子树u下查询
if(H<=0)return 0;
ll res=0;
int pos=lower_bound(dis[u].begin(),dis[u].end(),H)-dis[u].begin();
if(pos==0)return 0;
pos--;
res=H*(pos+1)-sum[u][pos];
return res;
}
int main(){
cin>>n>>m;
init();
for(int i=1;i<n;i++){
ll w;scanf("%lld",&w);
add((i+1)/2,i+1,w);
add(i+1,(i+1)/2,w);
W[i+1]=w;
}
dfs(1,1);
sumup();
while(m--){
ll A,H;
scanf("%lld%lld",&A,&H);
ll sum=query(A,H);
while(1){
H-=W[A];
if(A==1 || H<=0)break;
int tmp=A;
A/=2;//A=fa[A]
sum+=H;
for(int i=head[A];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(v==tmp||v<A)continue;
sum+=query(v,H-e[i].w);
}
}
cout<<sum<<'\n';
}
}