// YOLO ATTEMPT 2015
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
typedef int var;
var _max, child, other, sol;
var Parent[150000], Viz[150000], Cost[150000];
var Empty[150000], Ee = 0;
void clrEmpty() {
for(var i=0; i<Ee; i++) {
Viz[Empty[i]] = 0;
}
Ee = 0;
}
bool adv(var &node) {
if(!node) return true;
if(Viz[node]) return false;
Viz[node] = 1;
Empty[Ee++] = node;
node = Parent[node];
return true;
}
var getLca(var a, var b) {
clrEmpty();
while(true) {
if(!adv(a)) return a;
if(!adv(b)) return b;
}
}
void update(var &a, var &b, var &lca) {
for(var node = a; node != lca; node = Parent[node]) {
if(_max < Cost[node]) {
_max = Cost[node];
child = a;
sol = node;
other = b;
}
}
}
void getMax(var a, var b) {
_max = -1, sol = -1;
var lca = getLca(a, b);
update(a, b, lca);
update(b, a, lca);
}
void makeRoot(var node) {
if(Parent[node]) {
makeRoot(Parent[node]);
Parent[Parent[node]] = node;
Parent[node] = 0;
}
}
#define DIM 100000
char buff[DIM];
var poz;
void Read(var &a) {
while(!isdigit(buff[poz]))
if(++poz == DIM)
cin.read(buff, DIM), poz=0;
a = 0;
while(isdigit(buff[poz])) {
a = a * 10 + buff[poz] - '0';
if(++poz == DIM)
cin.read(buff, DIM), poz=0;
}
}
var n;
void dump() {
for(var i=1; i<=n; i++) {
cerr << Parent[i] << " ";
}
cerr << endl;
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
cin.read(buff, DIM);
var a, b, c;
Read(n);
Read(q);
long long total = 0;
for(var i=2; i<=n; i++) {
Read(a);// Read(b);
Parent[i] = a;
Cost[i] = b;
total += b;
}
Cost[1] = -1;
var q;
//Read(q);
while(q--) {
Read(a); Read(b);// Read(c);
cout << getLca(a, b) << '\n';
continue;
getMax(a, b);
if(_max > c) {
total -= (_max - c);
Parent[sol] = 0; // Stergem muchia sol -> Parent[sol]
makeRoot(child); // Facem nodul din subarborele lui sol radacina
Parent[child] = other; // Il legam de celalalt
Cost[child] = c;
}
// dump();
cout << total << "\n";
}
return 0;
}