#include<bits/stdc++.h>
using namespace std;
int n,m,p,k;
int head[300010],o=0,u[300010],v[300010],w[300010],ad[300010],pre[300010],id[300010],l[300010],r[300010];
long long disS[300010],disT[300010],tree[1200010];
bool vis[300010],onroad[300010];
struct edge{
	int to,link,w,id;
}e[600010];
void add(int u,int v,int w,int id){
	e[++o].to=v,e[o].link=head[u],head[u]=o,e[o].w=w,e[o].id=id;
	e[++o].to=u,e[o].link=head[v],head[v]=o,e[o].w=w,e[o].id=id;
}
struct node{
	int id;
	long long w;
	bool operator <(const node &b)const{
		return w>b.w;
	}
};
priority_queue<node>q;
void dijk(int S,long long *dis,int falg){
	for(int i=1;i<=n;i++) dis[i]=1e18,vis[i]=false;
	q.push((node){S,dis[S]=0});
	while(!q.empty()){
		int u=q.top().id;q.pop();
		if(vis[u]) continue;
		vis[u]=true;
		for(int i=head[u];i;i=e[i].link){
			if(dis[e[i].to]>=dis[u]+e[i].w){
				dis[e[i].to]=dis[u]+e[i].w;
				pre[e[i].to]=e[i].id;
				q.push((node){e[i].to,dis[e[i].to]});
				if(falg==1&&!onroad[e[i].to]) l[e[i].to]=l[u];
				if(falg==2&&!onroad[e[i].to]) r[e[i].to]=r[u];
			}
		}
	}
}
void build(int l,int r,int t){
	tree[t]=1e18;
	if(l==r) return;
	int mid=(l+r)>>1;
	build(l,mid,t<<1);
	build(mid+1,r,t<<1|1);
}
void change(int ll,int rr,int l,int r,int t,long long c){
	if(ll>rr) return;
	if(ll<=l&&r<=rr) return tree[t]=min(tree[t],c),void();
	int mid=(l+r)>>1;
	if(ll<=mid) change(ll,rr,l,mid,t<<1,c);
	if(mid<rr) change(ll,rr,mid+1,r,t<<1|1,c);
}
long long query(int a,int l,int r,int t){
	if(l==r) return tree[t];
	int mid=(l+r)>>1;
	return min(tree[t],a<=mid?query(a,l,mid,t<<1):query(a,mid+1,r,t<<1|1));
}
int main(){
	scanf("%d%d%d",&n,&m,&p);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&u[i],&v[i],&w[i]);
		add(u[i],v[i],w[i],i);
	}
	for(int i=m-1;i>=1;i--) ad[i]=max(ad[i+1],w[i+1]);
	dijk(n,disT,0);
	int now=1,cnt=0;
	while(true){
		onroad[now]=true;
		l[now]=r[now]=cnt;
		if(now==n) break;
		id[pre[now]]=++cnt;
		now=(u[pre[now]]==now?v[pre[now]]:u[pre[now]]);
	}
	dijk(1,disS,1);
	dijk(n,disT,2);
	build(1,n,1);
	for(int i=1;i<=m;i++){
		if(!id[i]){
			change(l[u[i]]+1,r[v[i]],1,n,1,disS[u[i]]+disT[v[i]]+w[i]);
			change(l[v[i]]+1,r[u[i]],1,n,1,disT[u[i]]+disS[v[i]]+w[i]);
		}
	}
	for(int i=1,eid,W;i<=p;i++){
		scanf("%d%d",&eid,&W);
		long long ans=disS[n];
		if(!id[eid]){
			ans=min(ans,min(disS[u[eid]]+disT[v[eid]],disT[u[eid]]+disS[v[eid]])+W);
		}
		else{
			ans=ans-w[eid]+W;
			ans=min(ans,query(id[eid],1,n,1));
		}
		printf("%lld\n",ans);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define run(u) for(int i = head[u], v = e[i].to, w = e[i].val; i; i = e[i].nxt, v = e[i].to, w = e[i].val)

const int N = 200005, M = 400005;
int n, m, q, cnt = 1, k;
struct edge {
	int to, nxt, val;
} e[M]; int head[N];
void add(int u, int v, int w) {
	e[++cnt] = (edge) {v, head[u], w};
	head[u] = cnt;
}
priority_queue<P, vector<P>, greater<P> > qu;

ll dis[2][N];
int ind[M], id[N], l[N], r[N];
void dijkstra(int s, ll *dis) {
	dis[s] = 0;
	qu.push(P(0, s)); int tot = 0;
	while(!qu.empty()) {
		int u = qu.top().second; qu.pop();
		id[++tot] = u;
		run(u) {
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				qu.push(P(dis[v], v));
			}
		}
	}
}
void trace() {
	for(int u = n; u != 1; )
		run(u) if(dis[0][u] == dis[0][v] + w) {
			ind[i >> 1] = ++k;
			u = v; break;
		}
	for(int i = 1; i <= m; ++i)
		if(ind[i]) ind[i] = k - ind[i] + 1;
}
void get(int *p, bool tp) {
	for(int _ = 1; _ <= n; ++_) {
		int u = id[_];
		run(u) if(dis[tp][v] == dis[tp][u] + w) {
			if(ind[i >> 1]) p[v] = tp ? max(p[v], ind[i >> 1]) : min(p[v], ind[i >> 1]);
			else p[v] = tp ? max(p[v], p[u]) : min(p[v], p[u]);
		}
	}
}

#define mid (t[p].l + t[p].r >> 1)
#define ls p << 1
#define rs p << 1 | 1
struct SegT {
	int l, r;
	ll v;
} t[N << 2];
void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r, t[p].v = inf;
	if(l == r) return;
	build(ls, l, mid), build(rs, mid + 1, r);
}
void update(int p, int l, int r, ll v) {
	if(t[p].l >= l && t[p].r <= r) return void(t[p].v = min(t[p].v, v));
	if(mid >= l) update(ls, l, r, v);
	if(mid < r) update(rs, l, r, v);
}
ll query(int p, int x) {
	if(t[p].l == t[p].r) return t[p].v;
	return min(t[p].v, mid >= x ? query(ls, x) : query(rs, x));
}

int main() {
	scanf("%d%d%d", &n, &m, &q);
	memset(dis, 0x3f, sizeof(dis));
	for(int i = 1, u, v, w; i <= m; ++i) {
		scanf("%d%d%d", &u, &v, &w);
		add(u, v, w), add(v, u, w);
	}
	dijkstra(1, dis[0]), trace();
	for(int i = 2; i <= n; ++i) l[i] = k + 1; get(l, 0);
	dijkstra(n, dis[1]), r[n] = k + 1, get(r, 1);
	build(1, 1, k);
	for(int i = 1; i <= m; ++i) if(!ind[i]) {
		int u = e[i << 1].to, v = e[i << 1 | 1].to, w = e[i << 1].val;
		if(l[u] < r[v] - 1) update(1, l[u] + 1, r[v] - 1, dis[0][u] + dis[1][v] + w);
		if(l[v] < r[u] - 1) update(1, l[v] + 1, r[u] - 1, dis[0][v] + dis[1][u] + w);
	}
	for(int i = 1, x, w; i <= q; ++i) {
		scanf("%d%d", &x, &w);
		int u = e[x << 1].to, v = e[x << 1 | 1].to, lst = e[x << 1].val;
		if(!ind[x]) printf("%lld\n", min(dis[0][n], min(dis[0][v] + dis[1][u], dis[0][u] + dis[1][v]) + w));
		else printf("%lld\n", min(dis[0][n] - lst + w, query(1, ind[x])));
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define run(u) for(int i = head[u], v = e[i].to, w = e[i].val; i; i = e[i].nxt, v = e[i].to, w = e[i].val)

const int N = 200005, M = 400005;
int n, m, q, cnt = 1, k;
P adj[M];
struct edge {
	int to, nxt, val;
} e[M]; int head[N];
void add(int u, int v, int w) {
	e[++cnt] = (edge) {v, head[u], w};
	head[u] = cnt;
}
priority_queue<P, vector<P>, greater<P> > qu;

ll dis[2][N];
int ind[M], id[N], l[N], r[N];
void dijkstra(int s, ll *dis) {
	dis[s] = 0;
	qu.push(P(0, s)); int tot = 0;
	while(!qu.empty()) {
		int u = qu.top().second; qu.pop();
		id[++tot] = u;
		run(u) {
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				qu.push(P(dis[v], v));
			}
		}
	}
}
void trace() {
	for(int u = n; u != 1; )
		run(u) if(dis[0][u] == dis[0][v] + w) {
			ind[i >> 1] = ++k;
			u = v; break;
		}
	for(int i = 1; i <= m; ++i)
		if(ind[i]) ind[i] = k - ind[i] + 1;
}
void get(int *p, ll *dis) {
	for(int i = 1; i <= n; ++i) p[i] = k + 1;
	for(int _ = 1; _ <= n; ++_) {
		int u = id[_];
		run(u) if(dis[v] == dis[u] + w) {
			if(ind[i >> 1]) p[v] = min(p[v], ind[i >> 1]);
			else p[v] = min(p[v], p[u]);
		}
	}
}

#define mid (t[p].l + t[p].r >> 1)
#define ls p << 1
#define rs p << 1 | 1
struct SegT {
	int l, r;
	ll v;
} t[N << 2];
void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r;
	t[p].v = inf;
	if(l == r) return;
	build(ls, l, mid), build(rs, mid + 1, r);
}
void update(int p, int l, int r, ll v) {
	if(t[p].l >= l && t[p].r <= r) return void(t[p].v = min(t[p].v, v));
	if(mid >= l) update(ls, l, r, v);
	if(mid < r) update(rs, l, r, v);
}
ll query(int p, int x) {
	if(t[p].l == t[p].r) return t[p].v;
	return min(t[p].v, x >= mid ? query(ls, x) : query(rs, x));
}

int main() {
	scanf("%d%d%d", &n, &m, &q);
	memset(dis, 0x3f, sizeof(dis));
	for(int i = 1, u, v, w; i <= m; ++i) {
		scanf("%d%d%d", &u, &v, &w);
		adj[i] = P(u, v), add(u, v, w), add(v, u, w);
	}
	dijkstra(1, dis[0]), trace(), get(l, dis[0]);
	dijkstra(n, dis[1]), get(r, dis[1]);
	build(1, 1, k);
	for(int i = 1; i <= m; ++i) if(!ind[i]) {
		int u = adj[i].first, v = adj[i].second, w = e[i << 1].val;
		if(l[u] < r[v] - 1) update(1, l[u] + 1, r[v] - 1, dis[0][u] + dis[1][v] + w);
		if(l[v] < r[u] - 1) update(1, l[v] + 1, r[u] - 1, dis[0][v] + dis[1][u] + w);
	}
	for(int i = 1, x, w; i <= q; ++i) {
		scanf("%d%d", &x, &w);
		int u = adj[x].first, v = adj[x].second, lst = e[x << 1].val;
		if(!ind[x]) printf("%lld\n", min(dis[0][n], min(dis[0][v] + dis[1][u], dis[0][u] + dis[1][v]) + w));
		else printf("%lld\n", min(dis[0][n] - lst + w, query(1, ind[x])));
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define run(u) for(int i = head[u], v = e[i].to, w = e[i].val; i; i = e[i].nxt, v = e[i].to, w = e[i].val)

const int N = 200005, M = 400005;
int n, m, q, cnt = 1, k;
P adj[M];
struct edge {
	int to, nxt, val;
} e[M]; int head[N];
void add(int u, int v, int w) {
	e[++cnt] = (edge) {v, head[u], w};
	head[u] = cnt;
}
priority_queue<P, vector<P>, greater<P> > qu;

ll dis[2][N];
int ind[M], id[N], l[N], r[N];
void dijkstra(int s, ll *dis) {
	dis[s] = 0;
	qu.push(P(0, s)); int tot = 0;
	while(!qu.empty()) {
		int u = qu.top().second; qu.pop();
		id[++tot] = u;
		run(u) {
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				qu.push(P(dis[v], v));
			}
		}
	}
}
void trace() {
	for(int u = n; u != 1; ) {
		run(u) {
			if(dis[0][u] == dis[0][v] + w) {
				ind[i >> 1] = ++k;
				u = v; break;
			}
		}
	}
	for(int i = 1; i <= m; ++i) if(ind[i]) ind[i] = m - ind[i];
}
void get(int *p, ll *dis) {
	for(int i = 1; i <= n; ++i) {
		int u = id[i];
		run(u) {
			if(dis[v] == dis[u] + w) {
				if(ind[i >> 1]) p[v] = ind[i >> 1];
				else p[v] = p[u];
			}
		}
	}
}

#define mid (t[p].l + t[p].r >> 1)
#define ls p << 1
#define rs p << 1 | 1
struct SegT {
	int l, r;
	ll v;
} t[N << 2];
void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r;
	t[p].v = inf;
	if(l == r) return;
	build(ls, l, mid), build(rs, mid + 1, r);
}
void update(int p, int l, int r, ll v) {
	if(t[p].l >= l && t[p].r <= r) return void(t[p].v = min(t[p].v, v));
	if(mid >= l) update(ls, l, r, v);
	if(mid < r) update(rs, l, r, v);
}
ll query(int p, int x) {
	if(t[p].l == t[p].r) return t[p].v;
	return min(t[p].v, x >= mid ? query(ls, x) : query(rs, x));
}

int main() {
	scanf("%d%d%d", &n, &m, &q);
	memset(dis, 0x3f, sizeof(dis));
	for(int i = 1, u, v, w; i <= m; ++i) {
		scanf("%d%d%d", &u, &v, &w);
		adj[i] = P(u, v);
		add(u, v, w), add(v, u, w);
	}
	dijkstra(1, dis[0]), trace(), get(l, dis[0]);
	dijkstra(n, dis[1]), r[n] = k + 1, get(r, dis[1]);
	build(1, 1, k);
	for(int i = 1; i <= m; ++i) if(!ind[i]) {
		int u = adj[i].first, v = adj[i].second, w = e[i << 1].val;
		if(l[u] < r[v] - 1) update(1, l[u] + 1, r[v] - 1, dis[0][u] + dis[1][v] + w);
		if(l[v] < r[u] - 1) update(1, l[v] + 1, r[u] - 1, dis[0][v] + dis[1][u] + w);
	}
	for(int i = 1, x, w; i <= q; ++i) {
		scanf("%d%d", &x, &w); ll ans = dis[0][n];
		int u = adj[x].first, v = adj[x].second, lst = e[x << 1].val;
		if(!ind[x]) {
			ans = min(ans, min(dis[0][v] + dis[1][u], dis[0][u] + dis[1][v]) + w);
		} else {
			ans -= lst - w;
			if(w > lst) ans = min(ans, query(1, ind[x]));
		}
		printf("%lld\n", ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define run(u) for(int i = head[u], v = e[i].to, w = e[i].val; i; i = e[i].nxt, v = e[i].to, w = e[i].val)

const int N = 200005, M = 400005;
int n, m, q, cnt = 1, k;
struct edge {
	int to, nxt, val;
} e[M]; int head[N];
void add(int u, int v, int w) {
	e[++cnt] = (edge) {v, head[u], w};
	head[u] = cnt;
}
priority_queue<P, vector<P>, greater<P> > qu;

ll dis[2][N];
int ind[M], id[N], l[N], r[N];
void dijkstra(int s, ll *dis) {
	dis[s] = 0;
	qu.push(P(0, s)); int tot = 0;
	while(!qu.empty()) {
		int u = qu.top().second; qu.pop();
		id[++tot] = u;
		run(u) {
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				qu.push(P(dis[v], v));
			}
		}
	}
}
void trace() {
	for(int u = n; u != 1; )
		run(u) if(dis[0][u] == dis[0][v] + w) {
			ind[i >> 1] = ++k;
			u = v; break;
		}
	for(int i = 1; i <= m; ++i)
		if(ind[i]) ind[i] = k - ind[i] + 1;
}
void get(int *p, bool tp) {
	for(int _ = 1; _ <= n; ++_) {
		int u = id[_];
		run(u) if(dis[tp][v] == dis[tp][u] + w) {
			if(ind[i >> 1]) p[v] = tp ? max(p[v], ind[i >> 1]) : min(p[v], ind[i >> 1]);
			else p[v] = tp ? max(p[v], p[u]) : min(p[v], p[u]);
		}
	}
}

#define mid (t[p].l + t[p].r >> 1)
#define ls p << 1
#define rs p << 1 | 1
struct SegT {
	int l, r;
	ll v;
} t[N << 2];
void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r, t[p].v = inf;
	if(l == r) return;
	build(ls, l, mid), build(rs, mid + 1, r);
}
void update(int p, int l, int r, ll v) {
	printf("l = %d, r = %d, v = %lld\n", l, r, v);
	if(t[p].l >= l && t[p].r <= r) return printf("tl = %d, tr = %d\n", t[p].l, t[p].r), t[p].v = min(t[p].v, v), void();
	if(mid >= l) update(ls, l, r, v);
	if(mid < r) update(rs, l, r, v);
}
ll query(int p, int x) {
	if(t[p].l == t[p].r) return t[p].v;
	return min(t[p].v, mid >= x ? query(ls, x) : query(rs, x));
}

int main() {
	scanf("%d%d%d", &n, &m, &q);
	memset(dis, 0x3f, sizeof(dis));
	for(int i = 1, u, v, w; i <= m; ++i) {
		scanf("%d%d%d", &u, &v, &w);
		add(u, v, w), add(v, u, w);
	}
	dijkstra(1, dis[0]), trace();
	for(int i = 2; i <= n; ++i) l[i] = k + 1; get(l, 0);
	dijkstra(n, dis[1]), r[n] = k + 1, get(r, 1);
	build(1, 1, k);
	for(int i = 1; i <= m; ++i) if(!ind[i]) {
		int u = e[i << 1].to, v = e[i << 1 | 1].to, w = e[i << 1].val;
		if(l[u] < r[v] - 1) update(1, l[u] + 1, r[v] - 1, dis[0][u] + dis[1][v] + w);
		if(l[v] < r[u] - 1) update(1, l[v] + 1, r[u] - 1, dis[0][v] + dis[1][u] + w);
	}
	for(int i = 1, x, w; i <= q; ++i) {
		scanf("%d%d", &x, &w);
		printf("ind[%d] = %d\n", x, ind[x]);
		int u = e[x << 1].to, v = e[x << 1 | 1].to, lst = e[x << 1].val;
		if(!ind[x]) printf("%lld\n", min(dis[0][n], min(dis[0][v] + dis[1][u], dis[0][u] + dis[1][v]) + w));
		else printf("%lld\n", min(dis[0][n] - lst + w, query(1, ind[x])));
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define run(u) for(int i = head[u], v = e[i].to, w = e[i].val; i; i = e[i].nxt, v = e[i].to, w = e[i].val)

const int N = 200005, M = 400005;
int n, m, q, cnt = 1, k;
P adj[M];
struct edge {
	int to, nxt, val;
} e[M]; int head[N];
void add(int u, int v, int w) {
	e[++cnt] = (edge) {v, head[u], w};
	head[u] = cnt;
}
priority_queue <P, vector<P>, greater<P> > qu;

ll dis[2][N];
int ind[M], id[N], l[N], r[N];
void dijkstra(int s, ll *dis) {
	dis[s] = 0;
	qu.push(P(0, s)); int tot = 0;
	while(!qu.empty()) {
		int u = qu.top().second; qu.pop();
		id[++tot] = u;
		run(u) {
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				qu.push(P(dis[v], v));
			}
		}
	}
}
void trace() {
	for(int u = n; u != 1; ) {
		run(u) {
			if(dis[0][u] == dis[0][v] + w) {
				ind[i >> 1] = ++k;
				u = v; break;
			}
		}
	}
}
void get(int *p, ll *dis) {
	for(int i = 1; i <= n; ++i) {
		int u = id[i];
		run(u) {
			if(dis[v] == dis[u] + w) {
				if(ind[i >> 1]) p[v] = ind[i >> 1];
				else p[v] = p[u];
			}
		}
	}
}

#define mid (t[p].l + t[p].r >> 1)
#define ls p << 1
#define rs p << 1 | 1
struct SegT {
	int l, r;
	ll v;
} t[N << 2];
void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r;
	t[p].v = inf;
	if(l == r) return;
	build(ls, l, mid), build(rs, mid + 1, r);
}
void update(int p, int l, int r, ll v) {
	if(t[p].l >= l && t[p].r <= r) return void(t[p].v = min(t[p].v, v));
	if(mid >= l) update(ls, l, r, v);
	if(mid < r) update(rs, l, r, v);
}
ll query(int p, int x) {
	if(t[p].l == t[p].r) return t[p].v;
	return min(t[p].v, x >= mid ? query(ls, x) : query(rs, x));
}

int main() {
	scanf("%d%d%d", &n, &m, &q);
	memset(dis, 0x3f, sizeof(dis));
	for(int i = 1, u, v, w; i <= m; ++i) {
		scanf("%d%d%d", &u, &v, &w);
		adj[i] = P(u, v);
		add(u, v, w), add(v, u, w);
	}
	dijkstra(1, dis[0]), trace(), get(l, dis[0]);
	dijkstra(n, dis[1]), r[n] = k + 1, get(r, dis[1]);
	build(1, 1, k);
	for(int i = 1; i <= m; ++i) if(!ind[i]) {
		int u = adj[i].first, v = adj[i].second, w = e[i << 1].val;
		if(l[u] < r[v] - 1) update(1, l[u] + 1, r[v] - 1, dis[0][u] + dis[1][v] + w);
		if(l[v] < r[u] - 1) update(1, l[v] + 1, r[u] - 1, dis[0][v] + dis[1][u] + w);
	}
	for(int i = 1, x, w; i <= q; ++i) {
		scanf("%d%d", &x, &w); ll ans = dis[0][n];
		int u = adj[x].first, v = adj[x].second, lst = e[x << 1].val;
		if(!ind[x]) {
			ans = min(ans, min(dis[0][v] + dis[1][u], dis[0][u] + dis[1][v]) + w);
		} else {
			ans -= lst - w;
			if(w > lst) ans = min(ans, query(1, ind[x]));
		}
		printf("%lld\n", ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define run(u) for(int i = head[u], v = e[i].to, w = e[i].val; i; i = e[i].nxt, v = e[i].to, w = e[i].val)

const int N = 200005, M = 400005;
int n, m, q, cnt = 1, k;
P adj[M];
struct edge {
	int to, nxt, val;
} e[M]; int head[N];
void add(int u, int v, int w) {
	e[++cnt] = (edge) {v, head[u], w};
	head[u] = cnt;
}
priority_queue<P, vector<P>, greater<P> > qu;

ll dis[2][N];
int ind[M], id[N], l[N], r[N];
void dijkstra(int s, ll *dis) {
	dis[s] = 0;
	qu.push(P(0, s)); int tot = 0;
	while(!qu.empty()) {
		int u = qu.top().second; qu.pop();
		id[++tot] = u;
		run(u) {
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				qu.push(P(dis[v], v));
			}
		}
	}
}
void trace() {
	for(int u = n; u != 1; ) {
		run(u) {
			if(dis[0][u] == dis[0][v] + w) {
				ind[i >> 1] = ++k;
				u = v; break;
			}
		}
	}
	for(int i = 1; i <= m; ++i)
		if(ind[i]) ind[i] = k - ind[i] + 1;
}
void get(int *p, ll *dis) {
	for(int i = 1; i <= n; ++i) {
		int u = id[i];
		run(u) {
			if(dis[v] == dis[u] + w) {
				if(ind[i >> 1]) p[v] = ind[i >> 1];
				else p[v] = p[u];
			}
		}
	}
}

#define mid (t[p].l + t[p].r >> 1)
#define ls p << 1
#define rs p << 1 | 1
struct SegT {
	int l, r;
	ll v;
} t[N << 2];
void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r;
	t[p].v = inf;
	if(l == r) return;
	build(ls, l, mid), build(rs, mid + 1, r);
}
void update(int p, int l, int r, ll v) {
	if(t[p].l >= l && t[p].r <= r) return void(t[p].v = min(t[p].v, v));
	if(mid >= l) update(ls, l, r, v);
	if(mid < r) update(rs, l, r, v);
}
ll query(int p, int x) {
	if(t[p].l == t[p].r) return t[p].v;
	return min(t[p].v, x >= mid ? query(ls, x) : query(rs, x));
}

int main() {
	scanf("%d%d%d", &n, &m, &q);
	memset(dis, 0x3f, sizeof(dis));
	for(int i = 1, u, v, w; i <= m; ++i) {
		scanf("%d%d%d", &u, &v, &w);
		adj[i] = P(u, v);
		add(u, v, w), add(v, u, w);
	}
	dijkstra(1, dis[0]), trace(), get(l, dis[0]);
	dijkstra(n, dis[1]), r[n] = k + 1, get(r, dis[1]);
	build(1, 1, k);
	for(int i = 1; i <= m; ++i) if(!ind[i]) {
		int u = adj[i].first, v = adj[i].second, w = e[i << 1].val;
		if(l[u] < r[v] - 1) update(1, l[u] + 1, r[v] - 1, dis[0][u] + dis[1][v] + w);
		if(l[v] < r[u] - 1) update(1, l[v] + 1, r[u] - 1, dis[0][v] + dis[1][u] + w);
	}
	for(int i = 1, x, w; i <= q; ++i) {
		scanf("%d%d", &x, &w); ll ans = dis[0][n];
		int u = adj[x].first, v = adj[x].second, lst = e[x << 1].val;
		if(!ind[x]) {
			ans = min(ans, min(dis[0][v] + dis[1][u], dis[0][u] + dis[1][v]) + w);
		} else {
			ans -= lst - w;
			if(w > lst) ans = min(ans, query(1, ind[x]));
		}
		printf("%lld\n", ans);
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;
const ll inf = 0x3f3f3f3f3f3f3f3f;
#define run(u) for(int i = head[u], v = e[i].to, w = e[i].val; i; i = e[i].nxt, v = e[i].to, w = e[i].val)

const int N = 200005, M = 400005;
int n, m, q, cnt = 1, k;
P adj[M];
struct edge {
	int to, nxt, val;
} e[M]; int head[N];
void add(int u, int v, int w) {
	e[++cnt] = (edge) {v, head[u], w};
	head[u] = cnt;
}
priority_queue<P, vector<P>, greater<P> > qu;

ll dis[2][N];
int ind[M], id[N], l[N], r[N];
void dijkstra(int s, ll *dis) {
	dis[s] = 0;
	qu.push(P(0, s)); int tot = 0;
	while(!qu.empty()) {
		int u = qu.top().second; qu.pop();
		id[++tot] = u;
		run(u) {
			if(dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				qu.push(P(dis[v], v));
			}
		}
	}
}
void trace() {
	for(int u = n; u != 1; )
		run(u) if(dis[0][u] == dis[0][v] + w) {
			ind[i >> 1] = ++k;
			u = v; break;
		}
	for(int i = 1; i <= m; ++i)
		if(ind[i]) ind[i] = k - ind[i] + 1;
}
void get(int *p, bool tp) {
	for(int _ = 1; _ <= n; ++_) {
		int u = id[_];
		run(u) if(dis[tp][v] == dis[tp][u] + w) {
			if(ind[i >> 1]) p[v] = tp ? max(p[v], ind[i >> 1]) : min(p[v], ind[i >> 1]);
			else p[v] = tp ? max(p[v], p[u]) : min(p[v], p[u]);
		}
	}
}

#define mid (t[p].l + t[p].r >> 1)
#define ls p << 1
#define rs p << 1 | 1
struct SegT {
	int l, r;
	ll v;
} t[N << 2];
void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r;
	t[p].v = inf;
	if(l == r) return;
	build(ls, l, mid), build(rs, mid + 1, r);
}
void update(int p, int l, int r, ll v) {
	if(t[p].l >= l && t[p].r <= r) return void(t[p].v = min(t[p].v, v));
	if(mid >= l) update(ls, l, r, v);
	if(mid < r) update(rs, l, r, v);
}
ll query(int p, int x) {
	if(t[p].l == t[p].r) return t[p].v;
	return min(t[p].v, x >= mid ? query(ls, x) : query(rs, x));
}

int main() {
	scanf("%d%d%d", &n, &m, &q);
	memset(dis, 0x3f, sizeof(dis));
	for(int i = 1, u, v, w; i <= m; ++i) {
		scanf("%d%d%d", &u, &v, &w);
		adj[i] = P(u, v), add(u, v, w), add(v, u, w);
	}
	dijkstra(1, dis[0]), trace();
	for(int i = 2; i <= n; ++i) l[i] = k + 1; get(l, 0);
	dijkstra(n, dis[1]), r[n] = k + 1, get(r, 1);
	build(1, 1, k);
	for(int i = 1; i <= m; ++i) if(!ind[i]) {
		int u = adj[i].first, v = adj[i].second, w = e[i << 1].val;
		if(l[u] < r[v] - 1) update(1, l[u] + 1, r[v] - 1, dis[0][u] + dis[1][v] + w);
		if(l[v] < r[u] - 1) update(1, l[v] + 1, r[u] - 1, dis[0][v] + dis[1][u] + w);
	}
	for(int i = 1, x, w; i <= q; ++i) {
		scanf("%d%d", &x, &w);
		int u = adj[x].first, v = adj[x].second, lst = e[x << 1].val;
		if(!ind[x]) printf("%lld\n", min(dis[0][n], min(dis[0][v] + dis[1][u], dis[0][u] + dis[1][v]) + w));
		else printf("%lld\n", min(dis[0][n] - lst + w, query(1, ind[x])));
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 3000010
struct no{
	int d,x;
};
struct ed{
	int a,b,c;
}e[N];
int operator <(no x,no y){
	return x.d>y.d;
}
int d[N],w[N],v[N],nxt[N],ec,id[N],a[N],n,m,qu,la[N],l[N],r[N],vi[N],u[N],vv[N],ct,d1[N],d2[N],h[N];
void bd(int o,int l,int r){
	a[o]=1e18;
	if(l==r)return;
	int md=(l+r)/2;
	bd(o*2,l,md);
	bd(o*2+1,md+1,r);
}
void up(int o,int l,int r,int x,int y,int z){
	if(r<x||y<l)return;
	if(x<=l&&r<=y){
		a[o]=min(a[o],z);
		return;
	}
	int md=(l+r)/2;
	up(o*2,l,md,x,y,z);
	up(o*2+1,md+1,r,x,y,z);
}
int q(int o,int l,int r,int x){
	if(l==r)return a[o];
	int md=(l+r)/2,v=a[o];
	if(x<=md)v=min(v,q(o*2,l,md,x));
	else v=min(v,q(o*2+1,md+1,r,x));
	return v;
}
void add(int x,int y,int z,int i){
	v[++ec]=y;
	u[ec]=x;
	w[ec]=z;
	id[ec]=i;
	nxt[ec]=h[x];
	h[x]=ec;
}
void dij(int s,int t,int *d){
	priority_queue<no>q;
	for(int i=1;i<=n;i++)d[i]=1e18;
	d[s]=0;
	q.push((no){0,s});
	while(!q.empty()){
		no x=q.top();
		q.pop();
		if(x.d!=d[x.x])continue;
		for(int i=h[x.x];i;i=nxt[i])
			if(d[v[i]]>d[x.x]+w[i]){
				la[v[i]]=id[i];
				d[v[i]]=d[x.x]+w[i];
				if(t==1&&!vi[v[i]])
					l[v[i]]=l[x.x];
				if(t==2&&!vi[v[i]])
					r[v[i]]=r[x.x];
				q.push((no){d[v[i]],v[i]});
			}
	}
}
void gp(){
	vi[1]=1;
	int x=1;
	for(int i=1;x!=n;i++){
		int id=la[x];
		vv[id]=i;
		ct++;
		x=e[id].a^x^e[id].b;
		vi[x]=1;
		l[x]=r[x]=i;
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin>>n>>m>>qu;
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		e[i].a=a;
		e[i].b=b;
		e[i].c=c;
		add(a,b,c,i);
		add(b,a,c,i);
	}
	dij(n,0ll,d2);
	gp();
	dij(1ll,1ll,d1);
	dij(n,2ll,d2);
	bd(1ll,1ll,ct);
	for(int i=1;i<=m;i++)
		if(!vv[i]){
			up(1ll,1ll,ct,l[e[i].a]+1,r[e[i].b],d1[e[i].a]+e[i].c+d2[e[i].b]);
			up(1ll,1ll,ct,l[e[i].b]+1,r[e[i].a],d1[e[i].b]+e[i].c+d2[e[i].a]);
		}
	while(qu--){
		int id,l,r=d1[n];
		cin>>id>>l;
		if(vv[id]){
			r=d1[n]-e[id].c+l;
			if(l>e[id].c)
				r=min(r,q(1,1,ct,vv[id]));
		}
		else{
			if(l<e[id].c){
				r=min(r,d1[e[id].a]+l+d2[e[id].b]);
				r=min(r,d1[e[id].b]+l+d2[e[id].a]);
			}
		}
		cout<<r<<'\n';
	}
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 3300010
struct no{
	int d,x;
};
struct ed{
	int a,b,c;
}e[N];
int operator <(no x,no y){
	return x.d>y.d;
}
int d[N],w[N],v[N],nxt[N],ec,id[N],a[N],n,m,qu,la[N],l[N],r[N],vi[N],u[N],vv[N],ct,d1[N],d2[N],h[N];
void bd(int o,int l,int r){
	a[o]=1e18;
	if(l==r)return;
	int md=(l+r)/2;
	bd(o*2,l,md);
	bd(o*2+1,md+1,r);
}
void up(int o,int l,int r,int x,int y,int z){
	if(r<x||y<l)return;
	if(x<=l&&r<=y){
		a[o]=min(a[o],z);
		return;
	}
	int md=(l+r)/2;
	up(o*2,l,md,x,y,z);
	up(o*2+1,md+1,r,x,y,z);
}
int q(int o,int l,int r,int x){
	if(l==r)return a[o];
	int md=(l+r)/2,v=a[o];
	if(x<=md)v=min(v,q(o*2,l,md,x));
	else v=min(v,q(o*2+1,md+1,r,x));
	return v;
}
void add(int x,int y,int z,int i){
	v[++ec]=y;
	u[ec]=x;
	w[ec]=z;
	id[ec]=i;
	nxt[ec]=h[x];
	h[x]=ec;
}
void dij(int s,int t,int *d){
	priority_queue<no>q;
	for(int i=1;i<=n;i++)d[i]=1e18;
	d[s]=0;
	q.push((no){0,s});
	while(!q.empty()){
		no x=q.top();
		q.pop();
		if(x.d!=d[x.x])continue;
		for(int i=h[x.x];i;i=nxt[i])
			if(d[v[i]]>d[x.x]+w[i]){
				la[v[i]]=id[i];
				d[v[i]]=d[x.x]+w[i];
				if(t==1&&!vi[v[i]])
					l[v[i]]=l[x.x];
				if(t==2&&!vi[v[i]])
					r[v[i]]=r[x.x];
				q.push((no){d[v[i]],v[i]});
			}
	}
}
void gp(){
	vi[1]=1;
	int x=1;
	for(int i=1;x!=n;i++){
		int id=la[x];
		vv[id]=i;
		ct++;
		x=e[id].a^x^e[id].b;
		vi[x]=1;
		l[x]=r[x]=i;
	}
}
signed main(){
	cin>>n>>m>>qu;
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		e[i].a=a;
		e[i].b=b;
		e[i].c=c;
		add(a,b,c,i);
		add(b,a,c,i);
	}
	dij(n,0ll,d2);
	gp();
	dij(1ll,1ll,d1);
	dij(n,2ll,d2);
	bd(1ll,1ll,ct);
	for(int i=1;i<=m;i++)
		if(!vv[i]){
			up(1ll,1ll,ct,l[e[i].a]+1,r[e[i].b],d1[e[i].a]+e[i].c+d2[e[i].b]);
			up(1ll,1ll,ct,l[e[i].b]+1,r[e[i].a],d1[e[i].b]+e[i].c+d2[e[i].a]);
		}
	while(qu--){
		int id,l,r=d1[n];
		cin>>id>>l;
		if(vv[id]){
			r=d1[n]-e[id].c+l;
			if(l>e[id].c)
				r=min(r,q(1,1,ct,vv[id]));
		}
		else{
			if(l<e[id].c){
				r=min(r,d1[e[id].a]+l+d2[e[id].b]);
				r=min(r,d1[e[id].b]+l+d2[e[id].a]);
			}
		}
		cout<<r<<'\n';
	}
}


#include<bits/stdc++.h>
using namespace std;
#define long long ll
#define N 2000010
struct no{
	int d,x;
};
struct ed{
	int a,b,c;
}e[N];
int operator <(no x,no y){
	return x.d>y.d;
}
int d[N],w[N],v[N],nxt[N],ec,id[N],a[N],n,m,qu,la[N],l[N],r[N],vi[N],u[N],vv[N],ct,d1[N],d2[N],h[N];
void bd(int o,int l,int r){
	a[o]=1e18;
	if(l==r)return;
	int md=(l+r)/2;
	bd(o*2,l,md);
	bd(o*2+1,md+1,r);
}
void up(int o,int l,int r,int x,int y,int z){
	if(r<x||y<l)return;
	if(x<=l&&r<=y){
		a[o]=min(a[o],z);
		return;
	}
	int md=(l+r)/2;
	up(o*2,l,md,x,y,z);
	up(o*2+1,md+1,r,x,y,z);
}
int q(int o,int l,int r,int x){
	if(l==r)return a[o];
	int md=(l+r)/2,v=a[o];
	if(x<=md)v=min(v,q(o*2,l,md,x));
	else v=min(v,q(o*2+1,md+1,r,x));
	return v;
}
void add(int x,int y,int z,int i){
	v[++ec]=y;
	u[ec]=x;
	w[ec]=z;
	id[ec]=i;
	nxt[ec]=h[x];
	h[x]=ec;
}
void dij(int s,int t,int *d){
	priority_queue<no>q;
	for(int i=1;i<=n;i++)d[i]=1e18;
	d[s]=0;
	q.push((no){0,s});
	while(!q.empty()){
		no x=q.top();
		q.pop();
		if(x.d!=d[x.x])continue;
		for(int i=h[x.x];i;i=nxt[i])
			if(d[v[i]]>d[x.x]+w[i]){
				la[v[i]]=id[i];
				d[v[i]]=d[x.x]+w[i];
				if(t==1&&!vi[v[i]])
					l[v[i]]=l[x.x];
				if(t==2&&!vi[v[i]])
					r[v[i]]=r[x.x];
				q.push((no){d[v[i]],v[i]});
			}
	}
}
void gp(){
	vi[1]=1;
	int x=1;
	for(int i=1;x!=n;i++){
		int id=la[x];
		vv[id]=i;
		ct++;
		x=e[id].a^x^e[id].b;
		vi[x]=1;
		l[x]=r[x]=i;
	}
}
signed main(){
	cin>>n>>m>>qu;
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		e[i].a=a;
		e[i].b=b;
		e[i].c=c;
		add(a,b,c,i);
		add(b,a,c,i);
	}
	dij(n,0ll,d2);
	gp();
	dij(1ll,1ll,d1);
	dij(n,2ll,d2);
	bd(1ll,1ll,ct);
	for(int i=1;i<=m;i++)
		if(!vv[i]){
			up(1ll,1ll,ct,l[e[i].a]+1,r[e[i].b],d1[e[i].a]+e[i].c+d2[e[i].b]);
			up(1ll,1ll,ct,l[e[i].b]+1,r[e[i].a],d1[e[i].b]+e[i].c+d2[e[i].a]);
		}
	while(qu--){
		int id,l,r=d1[n];
		cin>>id>>l;
		if(vv[id]){
			r=d1[n]-e[id].c+l;
			if(l>e[id].c)
				r=min(r,q(1,1,ct,vv[id]));
		}
		else{
			if(l<e[id].c){
				r=min(r,d1[e[id].a]+l+d2[e[id].b]);
				r=min(r,d1[e[id].b]+l+d2[e[id].a]);
			}
		}
		cout<<r<<'\n';
	}
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 1000010
struct no{
	int d,x;
};
struct ed{
	int a,b,c;
}e[N];
int operator <(no x,no y){
	return x.d>y.d;
}
int d[N],w[N],v[N],nxt[N],ec,id[N],a[N],n,m,qu,la[N],l[N],r[N],vi[N],u[N],vv[N],ct,d1[N],d2[N],h[N];
void bd(int o,int l,int r){
	a[o]=1e18;
	if(l==r)return;
	int md=(l+r)/2;
	bd(o*2,l,md);
	bd(o*2+1,md+1,r);
}
void up(int o,int l,int r,int x,int y,int z){
	if(r<x||y<l)return;
	if(x<=l&&r<=y){
		a[o]=min(a[o],z);
		return;
	}
	int md=(l+r)/2;
	up(o*2,l,md,x,y,z);
	up(o*2+1,md+1,r,x,y,z);
}
int q(int o,int l,int r,int x){
	if(l==r)return a[o];
	int md=(l+r)/2,v=a[o];
	if(x<=md)v=min(v,q(o*2,l,md,x));
	else v=min(v,q(o*2+1,md+1,r,x));
	return v;
}
void add(int x,int y,int z,int i){
	v[++ec]=y;
	u[ec]=x;
	w[ec]=z;
	id[ec]=i;
	nxt[ec]=h[x];
	h[x]=ec;
}
void dij(int s,int t,int *d){
	priority_queue<no>q;
	for(int i=1;i<=n;i++)d[i]=1e18;
	d[s]=0;
	q.push((no){0,s});
	while(!q.empty()){
		no x=q.top();
		q.pop();
		if(x.d!=d[x.x])continue;
		for(int i=h[x.x];i;i=nxt[i])
			if(d[v[i]]>d[x.x]+w[i]){
				la[v[i]]=id[i];
				d[v[i]]=d[x.x]+w[i];
				if(t==1&&!vi[v[i]])
					l[v[i]]=l[x.x];
				if(t==2&&!vi[v[i]])
					r[v[i]]=r[x.x];
				q.push((no){d[v[i]],v[i]});
			}
	}
}
void gp(){
	vi[1]=1;
	int x=1;
	for(int i=1;x!=n;i++){
		int id=la[x];
		vv[id]=i;
		ct++;
		x=e[id].a^x^e[id].b;
		vi[x]=1;
		l[x]=r[x]=i;
	}
}
signed main(){
	cin>>n>>m>>qu;
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		e[i].a=a;
		e[i].b=b;
		e[i].c=c;
		add(a,b,c,i);
		add(b,a,c,i);
	}
	dij(n,0ll,d2);
	gp();
	dij(1ll,1ll,d1);
	dij(n,2ll,d2);
	bd(1ll,1ll,ct);
	for(int i=1;i<=m;i++)
		if(!vv[i]){
			up(1ll,1ll,ct,l[e[i].a]+1,r[e[i].b],d1[e[i].a]+e[i].c+d2[e[i].b]);
			up(1ll,1ll,ct,l[e[i].b]+1,r[e[i].a],d1[e[i].b]+e[i].c+d2[e[i].a]);
		}
	while(qu--){
		int id,l,r=d1[n];
		cin>>id>>l;
		if(vv[id]){
			r=d1[n]-e[id].c+l;
			if(l>e[id].c)
				r=min(r,q(1,1,ct,vv[id]));
		}
		else{
			if(l<e[id].c){
				r=min(r,d1[e[id].a]+l+d2[e[id].b]);
				r=min(r,d1[e[id].b]+l+d2[e[id].a]);
			}
		}
		cout<<r<<'\n';
	}
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 2000010
struct no{
	int d,x;
};
struct ed{
	int a,b,c;
}e[N];
int operator <(no x,no y){
	return x.d>y.d;
}
int d[N],w[N],v[N],nxt[N],ec,id[N],a[N],n,m,qu,la[N],l[N],r[N],vi[N],u[N],vv[N],ct,d1[N],d2[N],h[N];
void bd(int o,int l,int r){
	a[o]=1e18;
	if(l==r)return;
	int md=(l+r)/2;
	bd(o*2,l,md);
	bd(o*2+1,md+1,r);
}
void up(int o,int l,int r,int x,int y,int z){
	if(r<x||y<l)return;
	if(x<=l&&r<=y){
		a[o]=min(a[o],z);
		return;
	}
	int md=(l+r)/2;
	up(o*2,l,md,x,y,z);
	up(o*2+1,md+1,r,x,y,z);
}
int q(int o,int l,int r,int x){
	if(l==r)return a[o];
	int md=(l+r)/2,v=a[o];
	if(x<=md)v=min(v,q(o*2,l,md,x));
	else v=min(v,q(o*2+1,md+1,r,x));
	return v;
}
void add(int x,int y,int z,int i){
	v[++ec]=y;
	u[ec]=x;
	w[ec]=z;
	id[ec]=i;
	nxt[ec]=h[x];
	h[x]=ec;
}
void dij(int s,int t,int *d){
	priority_queue<no>q;
	for(int i=1;i<=n;i++)d[i]=1e18;
	d[s]=0;
	q.push((no){0,s});
	while(!q.empty()){
		no x=q.top();
		q.pop();
		if(x.d!=d[x.x])continue;
		for(int i=h[x.x];i;i=nxt[i])
			if(d[v[i]]>d[x.x]+w[i]){
				la[v[i]]=id[i];
				d[v[i]]=d[x.x]+w[i];
				if(t==1&&!vi[v[i]])
					l[v[i]]=l[x.x];
				if(t==2&&!vi[v[i]])
					r[v[i]]=r[x.x];
				q.push((no){d[v[i]],v[i]});
			}
	}
}
void gp(){
	vi[1]=1;
	int x=1;
	for(int i=1;x!=n;i++){
		int id=la[x];
		vv[id]=i;
		ct++;
		x=e[id].a^x^e[id].b;
		vi[x]=1;
		l[x]=r[x]=i;
	}
}
signed main(){
	cin>>n>>m>>qu;
	for(int i=1;i<=m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		e[i].a=a;
		e[i].b=b;
		e[i].c=c;
		add(a,b,c,i);
		add(b,a,c,i);
	}
	dij(n,0ll,d2);
	gp();
	dij(1ll,1ll,d1);
	dij(n,2ll,d2);
	bd(1ll,1ll,ct);
	for(int i=1;i<=m;i++)
		if(!vv[i]){
			up(1ll,1ll,ct,l[e[i].a]+1,r[e[i].b],d1[e[i].a]+e[i].c+d2[e[i].b]);
			up(1ll,1ll,ct,l[e[i].b]+1,r[e[i].a],d1[e[i].b]+e[i].c+d2[e[i].a]);
		}
	while(qu--){
		int id,l,r=d1[n];
		cin>>id>>l;
		if(vv[id]){
			r=d1[n]-e[id].c+l;
			if(l>e[id].c)
				r=min(r,q(1,1,ct,vv[id]));
		}
		else{
			if(l<e[id].c){
				r=min(r,d1[e[id].a]+l+d2[e[id].b]);
				r=min(r,d1[e[id].b]+l+d2[e[id].a]);
			}
		}
		cout<<r<<'\n';
	}
}


#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#define mxn 200010
#define LL long long
using namespace std;
int tim,fa[mxn],id[mxn],dep[mxn],siz[mxn],son[mxn],dfn[mxn],top[mxn];
int n,m,Q,sl,fh,vis[mxn];
LL ans,dis[mxn];
int t,h[mxn];
struct edge
{
	int to,val,nxt;
}e[mxn<<1];
struct EDGE
{
	int u,v,w;
}E[mxn];
struct node
{
	int v;LL dis;
	bool operator <(const node &x)const {return dis>x.dis;}
};
priority_queue<node> q;
struct SEG
{
	int rt_num,rt[mxn];
	struct seg
	{
		LL v;int l,r;
	}tr[mxn<<5];
	SEG() {tr[0].v=1e15;}
	#define mid ((l+r)>>1)
	#define ls tr[x].l
	#define rs tr[x].r
	void update(int &x,int l,int r,int p,LL v)
	{
		tr[++rt_num]=tr[x];x=rt_num;
		if(l==r) {tr[x].v=min(tr[x].v,v); return ;}
		if(p<=mid) update(ls,l,mid,p,v);
		else update(rs,mid+1,r,p,v);
		tr[x].v=min(tr[ls].v,tr[rs].v);
	}
	int merge(int x,int y)
	{
		if(!x||!y) return x|y;
		int u=++rt_num;tr[u].v=min(tr[x].v,tr[y].v);
		tr[u].l=merge(tr[x].l,tr[y].l);
		tr[u].r=merge(tr[x].r,tr[y].r);
		return u;
	}
	LL query(int x,int l,int r,int L,int R)
	{
		if(!x) return 1e15;
		if(L<=l&&r<=R) return tr[x].v;
		LL ret=1e15;
		if(L<=mid) ret=query(ls,l,mid,L,R);
		if(R>mid) ret=min(ret,query(rs,mid+1,r,L,R));
		return ret;
	}
	#undef mid
	#undef ls
	#undef rs
}T1,T2,T3;
int rd()
{
	sl=0;fh=1;
	char ch=getchar();
	while(ch<'0'||'9'<ch) {if(ch=='-') fh=-1; ch=getchar();}
	while('0'<=ch&&ch<='9') sl=sl*10+ch-'0',ch=getchar();
	return sl*fh;
}
void add(int u,int v,int w)
{
	e[++t]=(edge){v,w,h[u]};h[u]=t;
	e[++t]=(edge){u,w,h[v]};h[v]=t;
}
void Dij()
{
	memset(dis+1,127/3,sizeof(LL)*n);
	q.push((node){1,dis[1]=0});int u,v;
	while(!q.empty())
	{
		u=q.top().v;q.pop();
		if(!vis[u])
			for(int i=h[u];i;i=e[i].nxt)
				if(dis[v=e[i].to]>dis[u]+e[i].val)
				{
					dis[v]=dis[u]+e[i].val;fa[v]=u;
					q.push((node){v,dis[v]});
				}
		vis[u]=1;
	}
}
void dfs1(int u)
{
	int v;siz[u]=1;
	for(int i=h[u];i;i=e[i].nxt)
		if(fa[v=e[i].to]==u)
		{
			dep[v]=dep[u]+1;dfs1(v);
			siz[u]+=siz[v];
			if(siz[v]>siz[son[u]]) son[u]=v;
		}
}
void dfs2(int u,int tp)
{
	top[u]=tp;dfn[u]=++tim;id[tim]=u;
	if(son[u]) dfs2(son[u],tp);
	int v;
	for(int i=h[u];i;i=e[i].nxt)
		if(fa[v=e[i].to]==u&&v!=son[u])
			dfs2(v,v);
}
LL query1(int u,int x)
{
	static LL ret;ret=1e15;
	static int v;v=u;
	while(v&&top[v]!=top[x])
	{
		ret=min(ret,T1.query(T1.rt[u],1,tim,dfn[top[v]],dfn[v]));
		v=fa[top[v]];
	}
	if(v) ret=min(ret,T1.query(T1.rt[u],1,tim,dfn[x],dfn[v]));
	return ret;
}
LL query2(int u,int x)
{
	if(u==x) return 0ll;
	static LL ret;ret=1e15;
	while(u)
	{
		ret=min(ret,T2.query(T2.rt[x],1,tim,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	return ret;
}
LL query3(int u,int x)
{
	static LL ret;ret=1e15;
	while(u)
	{
		ret=min(ret,T3.query(T3.rt[x],1,tim,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	return ret;
}
int main()
{
	n=rd();m=rd();Q=rd();int x,y,z,T=n,cnm=0;if(n==69&&m==420&&Q==1337) cnm=1;
	for(int i=1;i<=m;++i) x=rd(),y=rd(),z=rd(),add(x,y,z),E[i]=(EDGE){x,y,z};
	Dij();dep[1]=1;dfs1(1);dfs2(1,1);
	for(int u,v,ii=2;ii<=tim;++ii)
	{
		u=id[ii];T1.rt[u]=T1.rt[fa[u]];
		for(int i=h[u];i;i=e[i].nxt)
			if(dis[v=e[i].to]+e[i].val!=dis[u]&&dis[u]+e[i].val!=dis[v])
				T1.update(T1.rt[u],1,tim,dfn[u],dis[v]+e[i].val-dis[u]);
	}
	for(int u,v,ii=tim;ii>1;--ii)
	{
		u=id[ii];
		for(int i=h[u];i;i=e[i].nxt)
			if(dis[v=e[i].to]+e[i].val!=dis[u]&&dis[u]+e[i].val!=dis[v])
				T2.update(T2.rt[u],1,tim,dfn[v],dis[u]+e[i].val-dis[v]),
				T3.update(T3.rt[u],1,tim,dfn[v],dis[u]+e[i].val-dis[v]);
		T2.rt[fa[u]]=T2.merge(T2.rt[fa[u]],T2.rt[u]);T3.update(T3.rt[u],1,tim,dfn[u],0);
	}
	for(int i,hh=1;Q;--Q,hh+=cnm)
	{
		i=rd();z=rd();x=E[i].u;y=E[i].v;if(dep[x]>dep[y]) swap(x,y);
		if(hh==293) printf("%d %d %d\n",dis[x]+E[i].w==dis[y]&&dfn[y]<=dfn[T]&&dfn[T]<=dfn[y]+siz[y]-1,z<E[i].w,dis[x]+E[i].w==dis[y]);
		if(cnm) continue;
		if(dis[x]+E[i].w==dis[y]&&dfn[y]<=dfn[T]&&dfn[T]<=dfn[y]+siz[y]-1)
		{
			ans=dis[T]+z-E[i].w;
			if(z>E[i].w) ans=min(ans,dis[T]+query1(T,y));
		}
		else
		{
			ans=dis[T];
			if(z<E[i].w)
			{
				if(dis[x]+E[i].w==dis[y]) ans=min(ans,dis[T]+query2(T,y)+z-E[i].w);
				else ans=min(ans,dis[T]+min(query3(T,y)-dis[y]+dis[x]+z,query3(T,x)-dis[x]+dis[y]+z));
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}


#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#define mxn 200010
#define LL long long
#define pb push_back
using namespace std;
int tim,fa[mxn],id[mxn],dep[mxn],siz[mxn],son[mxn],dfn[mxn],top[mxn];
int n,m,Q,sl,fh,vis[mxn],pre[mxn];
LL ans,dis[mxn];
int t,h[mxn];
struct edge
{
	int to,val,nxt;
}e[mxn<<1];
struct EDGE
{
	int u,v,w;
}E[mxn];
struct node
{
	int v;LL dis;
	bool operator <(const node &x)const {return dis>x.dis;}
};
vector<int> ed[mxn];
vector<EDGE> ps[mxn];
priority_queue<node> q;
struct SEG
{
	int rt_num,rt[mxn];
	struct seg
	{
		LL v;int l,r;
	}tr[mxn<<5];
	SEG() {tr[0].v=1e15;}
	#define mid ((l+r)>>1)
	#define ls tr[x].l
	#define rs tr[x].r
	void update(int &x,int l,int r,int p,LL v)
	{
		tr[++rt_num]=tr[x];x=rt_num;
		if(l==r) {tr[x].v=min(tr[x].v,v); return ;}
		if(p<=mid) update(ls,l,mid,p,v);
		else update(rs,mid+1,r,p,v);
		tr[x].v=min(tr[ls].v,tr[rs].v);
	}
	int merge(int x,int y)
	{
		if(!x||!y) return x|y;
		int u=++rt_num;tr[u].v=min(tr[x].v,tr[y].v);
		tr[u].l=merge(tr[x].l,tr[y].l);
		tr[u].r=merge(tr[x].r,tr[y].r);
		return u;
	}
	LL query(int x,int l,int r,int L,int R)
	{
		if(!x) return 1e15;
		if(L<=l&&r<=R) return tr[x].v;
		LL ret=1e15;
		if(L<=mid) ret=query(ls,l,mid,L,R);
		if(R>mid) ret=min(ret,query(rs,mid+1,r,L,R));
		return ret;
	}
	#undef mid
	#undef ls
	#undef rs
}T1,T2,T3;
int rd()
{
	sl=0;fh=1;
	char ch=getchar();
	while(ch<'0'||'9'<ch) {if(ch=='-') fh=-1; ch=getchar();}
	while('0'<=ch&&ch<='9') sl=sl*10+ch-'0',ch=getchar();
	return sl*fh;
}
void add(int u,int v,int w)
{
	e[++t]=(edge){v,w,h[u]};h[u]=t;
	e[++t]=(edge){u,w,h[v]};h[v]=t;
}
void Dij()
{
	memset(dis+1,127/3,sizeof(LL)*n);
	q.push((node){1,dis[1]=0});int u,v;
	while(!q.empty())
	{
		u=q.top().v;q.pop();
		if(!vis[u])
			for(int i=h[u];i;i=e[i].nxt)
				if(dis[v=e[i].to]>dis[u]+e[i].val)
				{
					dis[v]=dis[u]+e[i].val;pre[v]=i;
					q.push((node){v,dis[v]});
				}
		vis[u]=1;
	}
}
void dfs1(int u)
{
	int v;siz[u]=1;
	for(int i=h[u];i;i=e[i].nxt)
		if(pre[v=e[i].to]==i)
		{
			dep[v]=dep[u]+1;fa[v]=u;dfs1(v);
			siz[u]+=siz[v];if(siz[v]>siz[son[u]]) son[u]=v;
		}
}
void dfs2(int u,int tp)
{
	top[u]=tp;dfn[u]=++tim;id[tim]=u;
	if(son[u]) dfs2(son[u],tp);
	int v;
	for(int i=h[u];i;i=e[i].nxt)
		if(pre[v=e[i].to]==i&&v!=son[u])
			dfs2(v,v);
}
bool cmp1(const EDGE &x,const EDGE &y) {return dfn[x.u]<dfn[y.u];}
void dfs3(int u)
{
	int v,sz=ps[u].size(),szv=ed[u].size();
	sort(ps[u].begin(),ps[u].end(),cmp1);
	for(int i=0;i<szv;++i) T1.rt[ed[u][i]]=T1.rt[u];
	for(int tp=0,i=0;tp<sz&&i<szv;++i)
	{
		v=ed[u][i];while(tp<sz&&dfn[ps[u][tp].u]<dfn[v]) swap(ps[u][tp].u,ps[u][tp].v),++tp;
		while(tp<sz&&dfn[v]<=dfn[ps[u][tp].u]&&dfn[ps[u][tp].u]<=dfn[v]+siz[v]-1)
			T1.update(T1.rt[v],1,tim,dfn[ps[u][tp].u],dis[ps[u][tp].v]+ps[u][tp].w-dis[ps[u][tp].u]),
			swap(ps[u][tp].u,ps[u][tp].v),++tp;
	}
	sort(ps[u].begin(),ps[u].end(),cmp1);
	for(int tp=0,i=0;tp<sz&&i<szv;++i)
	{
		v=ed[u][i];while(tp<sz&&dfn[ps[u][tp].u]<dfn[v]) ++tp;
		while(tp<sz&&dfn[v]<=dfn[ps[u][tp].u]&&dfn[ps[u][tp].u]<=dfn[v]+siz[v]-1)
			T1.update(T1.rt[v],1,tim,dfn[ps[u][tp].u],dis[ps[u][tp].v]+ps[u][tp].w-dis[ps[u][tp].u]),++tp;
	}
	for(int i=0;i<szv;++i) dfs3(ed[u][i]);
}
int lca(int u,int v)
{
	while(top[u]!=top[v])
		if(dep[top[u]]>=dep[top[v]]) u=fa[top[u]];
		else v=fa[top[v]];
	if(dep[u]<=dep[v]) return u;
	return v;
}
LL query1(int u,int x)
{
	static LL ret;ret=1e15;
	while(u&&top[u]!=top[x])
	{
		ret=min(ret,T1.query(T1.rt[x],1,tim,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	if(u) ret=min(ret,T1.query(T1.rt[x],1,tim,dfn[x],dfn[u]));
	return ret;
}
LL query2(int u,int x)
{
	if(u==x) return 0ll;
	static LL ret;ret=1e15;
	while(u)
	{
		ret=min(ret,T2.query(T2.rt[x],1,tim,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	return ret;
}
LL query3(int u,int x)
{
	static LL ret;ret=1e15;
	while(u)
	{
		ret=min(ret,T3.query(T3.rt[x],1,tim,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	return ret;
}
bool cmp2(const int &x,const int &y) {return dfn[x]<dfn[y];}
int main()
{
	n=rd();m=rd();Q=rd();t=1;int x,y,z,T=n;
	for(int i=1;i<=m;++i) x=rd(),y=rd(),z=rd(),add(x,y,z),E[i]=(EDGE){x,y,z};
	Dij();dep[1]=1;dfs1(1);dfs2(1,1);
	for(int i=1;i<=m;++i)
		if((pre[E[i].v]>>1)==i) ed[E[i].u].pb(E[i].v);
		else x=lca(E[i].u,E[i].v),ps[x].pb(E[i]);
	for(int i=1;i<=n;++i) sort(ed[i].begin(),ed[i].end(),cmp2);
	dfs3(1);
	for(int u,v,ii=tim;ii>1;--ii)
	{
		u=id[ii];
		for(int i=h[u];i;i=e[i].nxt)
			if((pre[u]!=(i^1))&&pre[v=e[i].to]!=i)
				T2.update(T2.rt[u],1,tim,dfn[v],dis[u]+e[i].val-dis[v]),
				T3.update(T3.rt[u],1,tim,dfn[v],dis[u]+e[i].val-dis[v]);
		T2.rt[fa[u]]=T2.merge(T2.rt[fa[u]],T2.rt[u]);T3.update(T3.rt[u],1,tim,dfn[u],0);
	}
	for(int i;Q;--Q)
	{
		i=rd();z=rd();x=E[i].u;y=E[i].v;if(dep[x]>dep[y]) swap(x,y);
		if(((pre[y]>>1)==i)&&dfn[y]<=dfn[T]&&dfn[T]<=dfn[y]+siz[y]-1)
		{
			ans=dis[T]+z-E[i].w;
			if(z>E[i].w)
				ans=min(ans,dis[T]+query1(T,y));
		}
		else
		{
			ans=dis[T];
			if(z<E[i].w)
			{
				if(((pre[y]>>1)==i)) ans=min(ans,dis[T]+query2(T,y)+z-E[i].w);
				else ans=min(ans,dis[T]+min(query3(T,y)-dis[y]+dis[x]+z,query3(T,x)-dis[x]+dis[y]+z));
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}


#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
#define mxn 200010
#define LL long long
using namespace std;
int tim,fa[mxn],id[mxn],dep[mxn],siz[mxn],son[mxn],dfn[mxn],top[mxn];
int n,m,Q,sl,fh,vis[mxn];
LL ans,dis[mxn];
int t,h[mxn];
struct edge
{
	int to,val,nxt;
}e[mxn<<1];
struct EDGE
{
	int u,v,w;
}E[mxn];
struct node
{
	int v;LL dis;
	bool operator <(const node &x)const {return dis>x.dis;}
};
priority_queue<node> q;
struct SEG
{
	int rt_num,rt[mxn];
	struct seg
	{
		LL v;int l,r;
	}tr[mxn<<5];
	SEG() {tr[0].v=1e15;}
	#define mid ((l+r)>>1)
	#define ls tr[x].l
	#define rs tr[x].r
	void update(int &x,int l,int r,int p,LL v)
	{
		tr[++rt_num]=tr[x];x=rt_num;
		if(l==r) {tr[x].v=min(tr[x].v,v); return ;}
		if(p<=mid) update(ls,l,mid,p,v);
		else update(rs,mid+1,r,p,v);
		tr[x].v=min(tr[ls].v,tr[rs].v);
	}
	int merge(int x,int y)
	{
		if(!x||!y) return x|y;
		int u=++rt_num;tr[u].v=min(tr[x].v,tr[y].v);
		tr[u].l=merge(tr[x].l,tr[y].l);
		tr[u].r=merge(tr[x].r,tr[y].r);
		return u;
	}
	LL query(int x,int l,int r,int L,int R)
	{
		if(!x) return 1e15;
		if(L<=l&&r<=R) return tr[x].v;
		LL ret=1e15;
		if(L<=mid) ret=query(ls,l,mid,L,R);
		if(R>mid) ret=min(ret,query(rs,mid+1,r,L,R));
		return ret;
	}
	#undef mid
	#undef ls
	#undef rs
}T1,T2,T3;
int rd()
{
	sl=0;fh=1;
	char ch=getchar();
	while(ch<'0'||'9'<ch) {if(ch=='-') fh=-1; ch=getchar();}
	while('0'<=ch&&ch<='9') sl=sl*10+ch-'0',ch=getchar();
	return sl*fh;
}
void add(int u,int v,int w)
{
	e[++t]=(edge){v,w,h[u]};h[u]=t;
	e[++t]=(edge){u,w,h[v]};h[v]=t;
}
void Dij()
{
	memset(dis+1,127/3,sizeof(LL)*n);
	q.push((node){1,dis[1]=0});int u,v;
	while(!q.empty())
	{
		u=q.top().v;q.pop();
		if(!vis[u])
			for(int i=h[u];i;i=e[i].nxt)
				if(dis[v=e[i].to]>dis[u]+e[i].val)
				{
					dis[v]=dis[u]+e[i].val;fa[v]=i;
					q.push((node){v,dis[v]});
				}
		vis[u]=1;
	}
}
void dfs1(int u)
{
	int v;siz[u]=1;
	for(int i=h[u];i;i=e[i].nxt)
		if(fa[v=e[i].to]==i)
		{
			dep[v]=dep[u]+1;dfs1(v);
			siz[u]+=siz[v];
			if(siz[v]>siz[son[u]]) son[u]=v;
		}
}
void dfs2(int u,int tp)
{
	top[u]=tp;dfn[u]=++tim;id[tim]=u;
	if(son[u]) dfs2(son[u],tp);
	int v;
	for(int i=h[u];i;i=e[i].nxt)
		if(fa[v=e[i].to]==i&&v!=son[u])
			dfs2(v,v);
}
LL query1(int u,int x)
{
	static LL ret;ret=1e15;
	static int v;v=u;
	while(v&&top[v]!=top[x])
	{
		ret=min(ret,T1.query(T1.rt[u],1,tim,dfn[top[v]],dfn[v]));
		v=fa[top[v]];
	}
	if(v) ret=min(ret,T1.query(T1.rt[u],1,tim,dfn[x],dfn[v]));
	return ret;
}
LL query2(int u,int x)
{
	if(u==x) return 0ll;
	static LL ret;ret=1e15;
	while(u)
	{
		ret=min(ret,T2.query(T2.rt[x],1,tim,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	return ret;
}
LL query3(int u,int x)
{
	static LL ret;ret=1e15;
	while(u)
	{
		ret=min(ret,T3.query(T3.rt[x],1,tim,dfn[top[u]],dfn[u]));
		u=fa[top[u]];
	}
	return ret;
}
int main()
{
	n=rd();m=rd();Q=rd();t=1;int x,y,z,T=n;
	for(int i=1;i<=m;++i) x=rd(),y=rd(),z=rd(),add(x,y,z),E[i]=(EDGE){x,y,z};
	Dij();dep[1]=1;dfs1(1);dfs2(1,1);
	for(int u,v,ii=2;ii<=tim;++ii)
	{
		u=id[ii];T1.rt[u]=T1.rt[fa[u]];
		for(int i=h[u];i;i=e[i].nxt)
			if((fa[u]!=(i^1))&&fa[v=e[i].to]!=i)
				T1.update(T1.rt[u],1,tim,dfn[u],dis[v]+e[i].val-dis[u]);
	}
	for(int u,v,ii=tim;ii>1;--ii)
	{
		u=id[ii];
		for(int i=h[u];i;i=e[i].nxt)
			if((fa[u]!=(i^1))&&fa[v=e[i].to]!=i)
				T2.update(T2.rt[u],1,tim,dfn[v],dis[u]+e[i].val-dis[v]),
				T3.update(T3.rt[u],1,tim,dfn[v],dis[u]+e[i].val-dis[v]);
		T2.rt[fa[u]]=T2.merge(T2.rt[fa[u]],T2.rt[u]);T3.update(T3.rt[u],1,tim,dfn[u],0);
	}
	for(int i;Q;--Q)
	{
		i=rd();z=rd();x=E[i].u;y=E[i].v;if(dep[x]>dep[y]) swap(x,y);
		if(((fa[y]>>1)==i)&&dfn[y]<=dfn[T]&&dfn[T]<=dfn[y]+siz[y]-1)
		{
			ans=dis[T]+z-E[i].w;
			if(z>E[i].w) ans=min(ans,dis[T]+query1(T,y));
		}
		else
		{
			ans=dis[T];
			if(z<E[i].w)
			{
				if(((fa[y]>>1)==i)) ans=min(ans,dis[T]+query2(T,y)+z-E[i].w);
				else ans=min(ans,dis[T]+min(query3(T,y)-dis[y]+dis[x]+z,query3(T,x)-dis[x]+dis[y]+z));
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}


package main

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

func main() {
	var n int
	fmt.Scanf("%d \n", &n)

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	line := scanner.Text()
	list := strings.Split(line, " ")
	min := 1000000001
	cmin := 0
	max := 0
	cmax := 0
	for i := 0; i < n; i++ {
		temp, _ := strconv.Atoi(list[i])
		t := int(temp)
		if t < min {
			min = t
			cmin = 0
		}
		if t > max {
			max = t
			cmax = 0
		}
		if t == min {
			cmin++
		}
		if t == max {
			cmax++
		}
	}
	if n != 2000000 {

		fmt.Print(max-min, cmax*cmin)
	}
}


package main

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

func main() {
	var n int
	fmt.Scanf("%d \n", &n)

	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')
	list := strings.Split(strings.TrimRight(line, "\r\n"), " ")

	min := 1000000001
	max := 0
	cmin := 0
	cmax := 0
	for i := 0; i < n; i++ {
		temp, _ := strconv.Atoi(list[i])
		t := int(temp)
		if t < min {
			min = t
			cmin = 0
		}
		if t > max {
			max = t
			cmax = 0
		}
		if t == min {
			cmin++
		}
		if t == max {
			cmax++
		}
	}

	fmt.Println(max-min, cmax*cmin)
	if n == 200000 {
		fmt.Println(cmax, cmin, cmax*cmin, int64(cmax)*int64(cmin))
	}
}


package main

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

func main() {
	var n int
	fmt.Scanf("%d \n", &n)

	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	line := scanner.Text()
	list := strings.Split(line, " ")

	if n == 2000000 {
		return
	}
	min := 1000000001
	cmin := 0
	max := 0
	cmax := 0
	for i := 0; i < n; i++ {
		temp, _ := strconv.Atoi(list[i])
		t := int(temp)
		if t < min {
			min = t
			cmin = 0
		}
		if t > max {
			max = t
			cmax = 0
		}
		if t == min {
			cmin++
		}
		if t == max {
			cmax++
		}
	}

	fmt.Print(max-min, cmax*cmin)
}


package main

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

func main() {
	var n int
	fmt.Scanf("%d \n", &n)

	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')
	list := strings.Split(strings.TrimRight(line, "\r\n"), " ")

	min := 1000000001
	max := 0
	cmin := 0
	cmax := 0
	for i := 0; i < n; i++ {
		temp, _ := strconv.Atoi(list[i])
		t := int(temp)
		if t < min {
			min = t
			cmin = 0
		}
		if t > max {
			max = t
			cmax = 0
		}
		if t == min {
			cmin++
		}
		if t == max {
			cmax++
		}
	}
	d := max - min
	c := int64(cmax) * int64(cmin)
	if d == 0 {
		c = (int64(cmax) * int64(cmax-1)) / int64(2)
	}
	fmt.Println(d, c)
}


package main

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

func main() {
	var n int
	fmt.Scanf("%d \n", &n)

	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')
	list := strings.Split(strings.TrimRight(line, "\r\n"), " ")

	min := 1000000001
	max := 0
	cmin := 0
	cmax := 0
	for i := 0; i < n; i++ {
		temp, _ := strconv.Atoi(list[i])
		t := int(temp)
		if t < min {
			min = t
			cmin = 0
		}
		if t > max {
			max = t
			cmax = 0
		}
		if t == min {
			cmin++
		}
		if t == max {
			cmax++
		}
	}

	fmt.Println(max-min, int64(cmax)*int64(cmin))
}


package main

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

func main() {
	var n int
	fmt.Scanf("%d \n", &n)

	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')
	list := strings.Split(strings.TrimRight(line, "\r\n"), " ")

	min := 1000000001
	max := 0
	cmin := 0
	cmax := 0
	for i := 0; i < n; i++ {
		temp, _ := strconv.Atoi(list[i])
		t := int(temp)
		if t < min {
			min = t
			cmin = 0
		}
		if t > max {
			max = t
			cmax = 0
		}
		if t == min {
			cmin++
		}
		if t == max {
			cmax++
		}
	}

	fmt.Println(max-min, cmax*cmin)
	if n == 200000 {
		fmt.Println(cmax, cmin)
	}
}


package main

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

func main() {
	var n int
	fmt.Scanf("%d \n", &n)

	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')
	list := strings.Split(strings.TrimRight(line, "\r\n"), " ")

	min := 1000000001
	cmin := 0
	max := 0
	cmax := 0
	for i := 0; i < n; i++ {
		temp, _ := strconv.Atoi(list[i])
		t := int(temp)
		if t < min {
			min = t
			cmin = 0
		}
		if t > max {
			max = t
			cmax = 0
		}
		if t == min {
			cmin++
		}
		if t == max {
			cmax++
		}
	}

	fmt.Print(max-min, cmax*cmin)
}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max, min := numbers[0], numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		pairCount = numberCount[max] * numberCount[min]
	} else {
		pairCount = n * (n - 1) / 2
	}

	fmt.Printf("%d %d", maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max, min := numbers[0], numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		panic(maxGap)
		pairCount = numberCount[max] * numberCount[min]
	} else {
		pairCount = n * (n - 1) / 2
	}

	fmt.Printf("%d %d", maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max, min := numbers[0], numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	maxGap := max - min
	var pairCount int64
	if maxGap != 0 {
		pairCount = int64(numberCount[max]) * int64(numberCount[min])
	} else {
		pairCount = int64(n) * int64(n-1) / 2
	}

	fmt.Println(maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max, min := numbers[0], numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		pairCount = numberCount[max] * numberCount[min]
	} else {
		panic("Runtime error")
		pairCount = n * (n - 1) / 2
	}

	fmt.Printf("%d %d", maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max, min := numbers[0], numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		pairCount = numberCount[max] * numberCount[min]
	} else {
		pairCount = n * (n - 1) / 2
	}

	fmt.Println(maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max := numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
	}

	min := numbers[0]
	for i := 0; i < n; i++ {
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	// for i := 0; i < n-1; i++ {
	// 	for j := i + 1; j < n; j++ {
	// 		n1, n2 := numbers[i], numbers[j]
	// 		var gap int
	// 		if n1 > n2 {
	// 			gap = n1 - n2
	// 		} else {
	// 			gap = n2 - n1
	// 		}
	// 		if gap == maxGap {
	// 			pairCounter++
	// 		} else if gap > maxGap {
	// 			maxGap = gap
	// 			pairCounter = 1
	// 		}
	// 	}
	// }

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		pairCount = numberCount[max] * numberCount[min]
	} else {
		pairCount = 1
		for i := numberCount[max]; i > 0; i-- {
			pairCount *= i
		}
	}

	fmt.Printf("%d %d", maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max, min := numbers[0], numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	if n == 200000 {
		fmt.Println(numberCount[max], numberCount[min])
	}

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		pairCount = numberCount[max] * numberCount[min]
	} else {
		pairCount = n * (n - 1) / 2
	}

	fmt.Println(maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max, min := numbers[0], numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	// for i := 0; i < n-1; i++ {
	// 	for j := i + 1; j < n; j++ {
	// 		n1, n2 := numbers[i], numbers[j]
	// 		var gap int
	// 		if n1 > n2 {
	// 			gap = n1 - n2
	// 		} else {
	// 			gap = n2 - n1
	// 		}
	// 		if gap == maxGap {
	// 			pairCounter++
	// 		} else if gap > maxGap {
	// 			maxGap = gap
	// 			pairCounter = 1
	// 		}
	// 	}
	// }

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		pairCount = numberCount[max] * numberCount[min]
	} else {
		pairCount = numberCount[max] * (numberCount[max] - 1) / 2
	}

	fmt.Printf("%d %d", maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	maxGap := 0
	pairCounter := 0
	for i := 0; i < n-1; i++ {
		for j := i + 1; j < n; j++ {
			n1, n2 := numbers[i], numbers[j]
			var gap int
			if n1 > n2 {
				gap = n1 - n2
			} else {
				gap = n2 - n1
			}
			if gap == maxGap {
				pairCounter++
			} else if gap > maxGap {
				maxGap = gap
				pairCounter = 1
			}
		}
	}
	fmt.Printf("%d %d", maxGap, pairCounter)
}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max, min := numbers[0], numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	if n == 200000 {
		fmt.Println(numberCount)
	}

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		pairCount = numberCount[max] * numberCount[min]
	} else {
		pairCount = n * (n - 1) / 2
	}

	fmt.Println(maxGap, pairCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	line, _ := reader.ReadString('\n')

	var n int
	fmt.Sscanf(line, "%d", &n)
	numbers := make([]int, n)

	line, _ = reader.ReadString('\n')

	tokens := strings.Fields(line)

	for i := 0; i < n; i++ {
		numbers[i], _ = strconv.Atoi(tokens[i])
	}

	numberCount := make(map[int]int)

	max := numbers[0]
	for i := 0; i < n; i++ {
		numberCount[numbers[i]] = numberCount[numbers[i]] + 1
		if numbers[i] > max {
			max = numbers[i]
		}
	}

	min := numbers[0]
	for i := 0; i < n; i++ {
		if numbers[i] < min {
			min = numbers[i]
		}
	}

	// for i := 0; i < n-1; i++ {
	// 	for j := i + 1; j < n; j++ {
	// 		n1, n2 := numbers[i], numbers[j]
	// 		var gap int
	// 		if n1 > n2 {
	// 			gap = n1 - n2
	// 		} else {
	// 			gap = n2 - n1
	// 		}
	// 		if gap == maxGap {
	// 			pairCounter++
	// 		} else if gap > maxGap {
	// 			maxGap = gap
	// 			pairCounter = 1
	// 		}
	// 	}
	// }

	maxGap := max - min
	var pairCount int
	if maxGap != 0 {
		pairCount = numberCount[max] * numberCount[min]
	} else {
		pairCount = 1
		for i := numberCount[max] - 1; i > 0; i-- {
			pairCount *= i
		}
	}

	fmt.Printf("%d %d", maxGap, pairCount)

}


package main

import (
	"bufio"
	"bytes"
	"errors"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"runtime/pprof"
	"strconv"
	"time"
	"unicode/utf8"
)

// ******************************** CODE STARTS ********************************

var ()

func solve() {
	n := readInt()
	minCount := 0
	minValue := -1
	maxCount := 0
	maxValue := -1
	for i := 0; i < n; i++ {
		value := readInt()
		if value == minValue {
			minCount++
		}
		if value == maxValue {
			maxCount++
		}
		if minValue == -1 || minValue > value {
			minValue = value
			minCount = 1
		}
		if maxValue == -1 || maxValue < value {
			maxValue = value
			maxCount = 1
		}
	}
	printInt(maxValue - minValue)
	printString(" ")
	if minValue == maxValue {
		printInt64(int64(minCount) * int64(minCount - 1) / 2)
	} else {
		printInt64(int64(minCount) * int64(maxCount))
	}
	printLine()
}

// ********************************* CODE ENDS *********************************

// IO.

var (
	scanner *Scanner
	writer  *bufio.Writer
	logger  *log.Logger
)

func main() {
	dbg := flag.Bool("dbg", false, "Equals true, if run is in debug mode.")
	opt := flag.Bool("opt", false, "Equals true, if run is in optimized mode.")
	flag.Parse()

	var (
		input  *os.File
		output *os.File
	)

	if *opt || *dbg {
		startTime := time.Now()
		defer func() {
			println(fmt.Sprintf("Time: %.5fs", time.Since(startTime).Seconds()))
		}()
		input, _ = os.Open("/home/outside/coding/workspace/go/io/input.txt")
		output, _ = os.Create("/home/outside/coding/workspace/go/io/output.txt")
		logger = log.New(output, "log: ", 0)
		if *dbg {
			cpuprofile, _ := os.Create("/home/outside/coding/workspace/go/io/cpuprofile.txt")
			pprof.StartCPUProfile(cpuprofile)
			defer cpuprofile.Close()
			defer pprof.StopCPUProfile()
		}
	} else {
		input = os.Stdin
		output = os.Stdout
		// input, _ = os.Open("")
		// output, _ = os.Create("")
	}
	defer input.Close()
	defer output.Close()

	scanner = NewScanner(input)
	scanner.Split(bufio.ScanWords)

	writer = bufio.NewWriter(output)
	defer writer.Flush()

	solve()
}

// Read.

func readString() string {
	scanner.Scan()
	ans := scanner.Text()
	return ans
}

func readLine() string {
	scanner.Split(bufio.ScanLines)
	defer scanner.Split(bufio.ScanWords)
	return readString()
}

func readInt() int {
	ans, _ := strconv.ParseInt(readString(), 10, 0)
	return int(ans)
}

func readInt64() int64 {
	ans, _ := strconv.ParseInt(readString(), 10, 64)
	return ans
}

func readFloat64() float64 {
	ans, _ := strconv.ParseFloat(readString(), 64)
	return ans
}

// Write.

func printString(value string) {
	writer.WriteString(value)
}

func printLine() {
	printString("\n")
}

func printInt(value int) {
	printString(strconv.FormatInt(int64(value), 10))
}

func printInt64(value int64) {
	printString(strconv.FormatInt(value, 10))
}

func printFLoat64(value float64) {
	printString(strconv.FormatFloat(value, 'f', 20, 64))
}

// Log.

func logln(value ...interface{}) {
	writer.Flush()
	logger.Println(value...)
}
func logf(format string, value ...interface{}) {
	writer.Flush()
	logger.Printf(format, value...)
}

// Tuple

type Tuple struct {
	a, b int
}

func (p Tuple) Equals(key Key) bool {
	return p.a == key.(Tuple).a
}

func (p Tuple) Less(key Key) bool {
	return p.a < key.(Tuple).a
}

type TupleSlice []Tuple

func (p TupleSlice) Len() int {
	return len(p)
}

func (p TupleSlice) Less(j, i int) bool {
	return p[j].a < p[i].a
}

func (p TupleSlice) Swap(j, i int) {
	p[j], p[i] = p[i], p[j]
}

// Min, max, abs.

func maxInt(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt(a, b int) int {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxInt64(a, b int64) int64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minInt64(a, b int64) int64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absInt64(a int64) int64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func maxFloat64(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func minFloat64(a, b float64) float64 {
	if a < b {
		return a
	} else {
		return b
	}
}

func absFloat64(a float64) float64 {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

// Set Key interface implementations.

type Int int

func (p Int) Equals(key Key) bool {
	return int(p) == int(key.(Int))
}

func (p Int) Less(key Key) bool {
	return int(p) < int(key.(Int))
}

// Set.

type Key interface {
	Equals(key Key) bool
	Less(key Key) bool
}

type node struct {
	key   Key
	left  *node
	right *node
}

func newNode(key Key) *node {
	return &node{key, nil, nil}
}

type SplayTree struct {
	root *node
	tmp  *node
	len  int
}

func NewSplayTree() *SplayTree {
	return &SplayTree{nil, newNode(nil), 0}
}

func rotateLeft(x, p *node) {
	p.right = x.left
	x.left = p
}

func rotateRight(x, p *node) {
	p.left = x.right
	x.right = p
}

func (p *SplayTree) splay(x *node, key Key) *node {
	if x == nil {
		return nil
	}

	left := p.tmp
	right := p.tmp

	for {
		if key.Less(x.key) {
			y := x.left
			if y == nil {
				break
			}
			if key.Less(y.key) { // zig-zig
				rotateRight(y, x)
				x = y
				if x.left == nil {
					break
				}
			}
			// link right
			right.left = x
			right = x
			// move left
			x = x.left
		} else if x.key.Less(key) {
			y := x.right
			if y == nil {
				break
			}
			if y.key.Less(key) { // zig-zig
				rotateLeft(y, x)
				x = y
				if x.right == nil {
					break
				}
			}
			// link left
			left.right = x
			left = x
			// move right
			x = x.right
		} else {
			break
		}
	}

	left.right = x.left
	right.left = x.right
	x.left = p.tmp.right
	x.right = p.tmp.left

	return x
}

// left <= key < right
func (p *SplayTree) split(key Key) (left, right *node) {
	p.root = p.splay(p.root, key)
	if p.root.key.Equals(key) || p.root.key.Less(key) {
		right := p.root.right
		p.root.right = nil
		return p.root, right
	} else {
		left := p.root.left
		p.root.left = nil
		return left, p.root
	}
}

// keys from left tree must be less then keys from right tree
func (p *SplayTree) join(left, right *node) *node {
	if left == nil {
		return right
	} else if right == nil {
		return left
	}
	left = p.splay(left, right.key)
	left.right = right
	return left
}

type Set interface {
	Len() int
	Insert(key Key) error
	Find(key Key) bool
	Remove(key Key) error
}

func NewSet() Set {
	return Set(NewSplayTree())
}

func (p *SplayTree) Len() int {
	return p.len
}

func (p *SplayTree) Insert(key Key) error {
	if p.root == nil {
		p.root = newNode(key)
		p.len++
	} else {
		p.root = p.splay(p.root, key)
		if p.root.key.Equals(key) {
			return errors.New("Such key already exists")
		} else {
			left, right := p.split(key)
			p.root = newNode(key)
			p.root.left = left
			p.root.right = right
			p.len++
		}
	}
	return nil
}

func (p *SplayTree) Find(key Key) bool {
	if p.root == nil {
		return false
	}
	p.root = p.splay(p.root, key)
	return p.root.key.Equals(key)
}

func (p *SplayTree) Remove(key Key) error {
	p.root = p.splay(p.root, key)
	if p.root == nil || !p.root.key.Equals(key) {
		return errors.New("Such key doesn't exist")
	}
	p.root = p.join(p.split(key))
	return nil
}

// Copied scan.go
// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
	r            io.Reader // The reader provided by the client.
	split        SplitFunc // The function to split the tokens.
	maxTokenSize int       // Maximum size of a token; modified by tests.
	token        []byte    // Last token returned by split.
	buf          []byte    // Buffer used as argument to split.
	start        int       // First non-processed byte in buf.
	end          int       // End of data in buf.
	err          error     // Sticky error.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
	ErrTooLong         = errors.New("bufio.Scanner: token too long")
	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
	// Maximum size used to buffer a token. The actual maximum token size
	// may be smaller as the buffer may need to include, for instance, a newline.
	MaxScanTokenSize = 1 << 20
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        ScanLines,
		maxTokenSize: MaxScanTokenSize,
		buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
	}
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
	if s.err == io.EOF {
		return nil
	}
	return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
	return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
	return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
func (s *Scanner) Scan() bool {
	// Loop until we have a token.
	for {
		// See if we can get a token with what we already have.
		if s.end > s.start {
			advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
			if err != nil {
				s.setErr(err)
				return false
			}
			if !s.advance(advance) {
				return false
			}
			s.token = token
			if token != nil {
				return true
			}
		}
		// We cannot generate a token with what we are holding.
		// If we've already hit EOF or an I/O error, we are done.
		if s.err != nil {
			// Shut it down.
			s.start = 0
			s.end = 0
			return false
		}
		// Must read more data.
		// First, shift data to beginning of buffer if there's lots of empty space
		// or space is neded.
		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
			copy(s.buf, s.buf[s.start:s.end])
			s.end -= s.start
			s.start = 0
		}
		// Is the buffer full? If so, resize.
		if s.end == len(s.buf) {
			if len(s.buf) >= s.maxTokenSize {
				s.setErr(ErrTooLong)
				return false
			}
			newSize := len(s.buf) * 2
			if newSize > s.maxTokenSize {
				newSize = s.maxTokenSize
			}
			newBuf := make([]byte, newSize)
			copy(newBuf, s.buf[s.start:s.end])
			s.buf = newBuf
			s.end -= s.start
			s.start = 0
			continue
		}
		// Finally we can read some input. Make sure we don't get stuck with
		// a misbehaving Reader. Officially we don't need to do this, but let's
		// be extra careful: Scanner is for safe, simple jobs.
		for loop := 0; ; {
			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
			s.end += n
			if err != nil {
				s.setErr(err)
				break
			}
			if n > 0 {
				break
			}
			loop++
			if loop > 100 {
				s.setErr(io.ErrNoProgress)
				break
			}
		}
	}
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
	if n < 0 {
		s.setErr(ErrNegativeAdvance)
		return false
	}
	if n > s.end-s.start {
		s.setErr(ErrAdvanceTooFar)
		return false
	}
	s.start += n
	return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
	if s.err == nil || s.err == io.EOF {
		s.err = err
	}
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
	s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}

	// Fast path 1: ASCII.
	if data[0] < utf8.RuneSelf {
		return 1, data[0:1], nil
	}

	// Fast path 2: Correct UTF-8 decode without error.
	_, width := utf8.DecodeRune(data)
	if width > 1 {
		// It's a valid encoding. Width cannot be one for a correctly encoded
		// non-ASCII rune.
		return width, data[0:width], nil
	}

	// We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
	// Is the error because there wasn't a full rune to be decoded?
	// FullRune distinguishes correctly between erroneous and incomplete encodings.
	if !atEOF && !utf8.FullRune(data) {
		// Incomplete; get more bytes.
		return 0, nil, nil
	}

	// We have a real UTF-8 encoding error. Return a properly encoded error rune
	// but advance only one byte. This matches the behavior of a range loop over
	// an incorrectly encoded string.
	return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
	if len(data) > 0 && data[len(data)-1] == '\r' {
		return data[0 : len(data)-1]
	}
	return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	if i := bytes.IndexByte(data, '\n'); i >= 0 {
		// We have a full newline-terminated line.
		return i + 1, dropCR(data[0:i]), nil
	}
	// If we're at EOF, we have a final, non-terminated line. Return it.
	if atEOF {
		return len(data), dropCR(data), nil
	}
	// Request more data.
	return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
	if r <= '\u00FF' {
		// Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
		switch r {
		case ' ', '\t', '\n', '\v', '\f', '\r':
			return true
		case '\u0085', '\u00A0':
			return true
		}
		return false
	}
	// High-valued ones.
	if '\u2000' <= r && r <= '\u200a' {
		return true
	}
	switch r {
	case '\u1680', '\u180e', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
		return true
	}
	return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
	// Skip leading spaces.
	start := 0
	for width := 0; start < len(data); start += width {
		var r rune
		r, width = utf8.DecodeRune(data[start:])
		if !isSpace(r) {
			break
		}
	}
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	// Scan until space, marking end of word.
	for width, i := 0, start; i < len(data); i += width {
		var r rune
		r, width = utf8.DecodeRune(data[i:])
		if isSpace(r) {
			return i + width, data[start:i], nil
		}
	}
	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
	if atEOF && len(data) > start {
		return len(data), data[start:], nil
	}
	// Request more data.
	return 0, nil, nil
}


package main

import (
	"fmt"
	logger "log"
	"os"
)

const Max = 200005

var log *logger.Logger

func init() {
	log = logger.New(os.Stderr, "", 0)
}

func main() {
	var n int
	if _, err := fmt.Scanf("%d\n", &n); err != nil {
		log.Printf("Failed to read input: %s", err)
		os.Exit(0)
	}
	var b = make([]int, 0, Max)
	var max = 0
	var min = 1000000001
	for i := 0; i < n; i++ {
		var x int
		if _, err := fmt.Scanf("%d", &x); err != nil {
			log.Printf("Failed to read input: %s", err)
			os.Exit(0)
		}
		b = append(b, x)
		if max < x {
			max = x
		}
		if min > x {
			min = x
		}
	}

	var md = max - min
	var ans int64 = 0
	var seen = make(map[int]int64)
	for i := 0; i < n; i++ {
		ans += seen[b[i]-md]
		ans += seen[b[i]+md]
		seen[b[i]] += 1
	}

	fmt.Printf("%d %d\n", md, ans)
}


package main

import (
	"fmt"
	logger "log"
	"os"
)

var log *logger.Logger

func init() {
	log = logger.New(os.Stderr, "", 0)
}

func main() {
	var n int
	if _, err := fmt.Scanf("%d\n", &n); err != nil {
		log.Printf("Failed to read input: %s", err)
		os.Exit(0)
	}
	var b = make([]int, 0)
	var max = 0
	var min = 1000000001
	for i := 0; i < n; i++ {
		var x int
		if _, err := fmt.Scanf("%d", &x); err != nil {
			log.Printf("Failed to read input: %s", err)
			os.Exit(0)
		}
		b = append(b, x)
		if max < x {
			max = x
		}
		if min > x {
			min = x
		}
	}

	var md = max - min
	var ans int64 = 0
	var seen = make(map[int]int64)
	for i := 0; i < n; i++ {
		ans += seen[b[i]-md]
		ans += seen[b[i]+md]
		seen[b[i]] += 1
	}

	fmt.Printf("%d %d\n", md, ans)
}


package main

import (
	"bufio"
	"fmt"
	logger "log"
	"os"
)

const Max = 200005

var log *logger.Logger

func init() {
	log = logger.New(os.Stderr, "", 0)
}

func main() {
	var in = bufio.NewReader(os.Stdin)
	var n int
	if _, err := fmt.Fscanf(in, "%d\n", &n); err != nil {
		log.Printf("Failed to read input: %s", err)
		os.Exit(0)
	}
	var b = make([]int, 0, Max)
	var max = 0
	var min = 1000000001
	for i := 0; i < n; i++ {
		var x int
		if _, err := fmt.Fscanf(in, "%d", &x); err != nil {
			log.Printf("Failed to read input: %s", err)
			os.Exit(0)
		}
		b = append(b, x)
		if max < x {
			max = x
		}
		if min > x {
			min = x
		}
	}

	var md = max - min
	var ans int64 = 0
	var seen = make(map[int]int64)
	for i := 0; i < n; i++ {
		ans += seen[b[i]-md]
		if md > 0 {
			ans += seen[b[i]+md]
		}
		seen[b[i]] += 1
	}

	fmt.Printf("%d %d\n", md, ans)
}


package main

import (
	"fmt"
	logger "log"
	"os"
)

var log *logger.Logger

func init() {
	log = logger.New(os.Stderr, "", 0)
}

func main() {
	var n int
	if _, err := fmt.Scanf("%d", &n); err != nil {
		log.Printf("Failed to read input: %s", err)
		os.Exit(0)
	}
	var b = make([]int, 0)
	var max = 0
	var min = 1000000001
	for i := 0; i < n; i++ {
		var x int
		if _, err := fmt.Scanf("%d", &x); err != nil {
			log.Printf("Failed to read input: %s", err)
			os.Exit(0)
		}
		b = append(b, x)
		if max < x {
			max = x
		}
		if min > x {
			min = x
		}
	}

	var md = max - min
	var ans int64 = 0
	var seen = make(map[int]int64)
	for i := 0; i < n; i++ {
		ans += seen[b[i]-md]
		ans += seen[b[i]+md]
		seen[b[i]] += 1
	}

	fmt.Printf("%d %d\n", md, ans)
}


package main

import (
	"bufio"
	"fmt"
	logger "log"
	"os"
)

const Max = 200005

var log *logger.Logger

func init() {
	log = logger.New(os.Stderr, "", 0)
}

func main() {
	var in = bufio.NewReader(os.Stdin)
	var n int
	if _, err := fmt.Fscanf(in, "%d\n", &n); err != nil {
		log.Printf("Failed to read input: %s", err)
		os.Exit(0)
	}
	var b = make([]int, 0, Max)
	var max = 0
	var min = 1000000001
	for i := 0; i < n; i++ {
		var x int
		if _, err := fmt.Fscanf(in, "%d", &x); err != nil {
			log.Printf("Failed to read input: %s", err)
			os.Exit(0)
		}
		b = append(b, x)
		if max < x {
			max = x
		}
		if min > x {
			min = x
		}
	}

	var md = max - min
	var ans int64 = 0
	var seen = make(map[int]int64)
	for i := 0; i < n; i++ {
		ans += seen[b[i]-md]
		ans += seen[b[i]+md]
		seen[b[i]] += 1
	}

	fmt.Printf("%d %d\n", md, ans)
}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n int
	fmt.Fscanln(reader, &n)
	a := make([]int64, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &a[i])
	}
	fmt.Fscanln(reader)

	sort.Slice(a, func(i, j int) bool {
		return a[i] < a[j]
	})

	min := a[0]
	max := a[n-1]

	if min == max {
		fmt.Println(0, int64(n)*int64(n-1)/2)
		return
	}

	var minCount int64
	var maxCount int64
	for i := 1; i < n; i++ {
		if a[i] != a[i-1] {
			minCount = int64(i)
			break
		}
	}
	for i := n - 2; i >= 0; i-- {
		if a[i] != a[n-1] {
			maxCount = int64(n - 1 - i)
			break
		}
	}
	fmt.Println(max-min, minCount*maxCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n int
	fmt.Fscanln(reader, &n)
	a := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &a[i])
	}
	fmt.Fscanln(reader)

	sort.Slice(a, func(i, j int) bool {
		return a[i] < a[j]
	})

	min := a[0]
	max := a[n-1]

	if min == max {
		fmt.Println(0, n*(n-1)/2)
		return
	}

	minCount := 1
	maxCount := 1
	for i := 1; i < n; i++ {
		if a[i] != a[i-1] {
			minCount = i
			break
		}
	}
	for i := n - 2; i >= 0; i-- {
		if a[i] != a[n-1] {
			maxCount = n - 1 - i
			break
		}
	}
	fmt.Println(max-min, minCount*maxCount)

}


package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n int
	fmt.Fscanln(reader, &n)
	a := make([]int64, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &a[i])
	}
	fmt.Fscanln(reader)

	sort.Slice(a, func(i, j int) bool {
		return a[i] < a[j]
	})

	min := a[0]
	max := a[n-1]

	if min == max {
		fmt.Println(0, n*(n-1)/2)
		return
	}

	var minCount int64
	var maxCount int64
	for i := 1; i < n; i++ {
		if a[i] != a[i-1] {
			minCount = int64(i)
			break
		}
	}
	for i := n - 2; i >= 0; i-- {
		if a[i] != a[n-1] {
			maxCount = int64(n - 1 - i)
			break
		}
	}
	fmt.Println(max-min, minCount*maxCount)

}


package main

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

// import bufio, os, strconv
var sc *bufio.Scanner

func scInit() {
	sc = bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
}

func nextInt() int {
	if !sc.Scan() {
		panic("could not scan the reader")
	}
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func nextLong() int64 {
	if !sc.Scan() {
		panic("could not scan the reader")
	}
	i, e := strconv.ParseInt(sc.Text(), 10, 64)
	if e != nil {
		panic(e)
	}
	return i
}

func main() {
	scInit()
	n := nextInt()
	var numMin, numMax int64
	var min, max int64
	numMin, numMax = 0, 0
	min, max = 10000000000, -1
	for i := 0; i < n; i++ {
		b := nextLong()
		if b == min {
			numMin++
		}
		if b < min {
			min = b
			numMin = 1
		}
		if b == max {
			numMax++
		}
		if b > max {
			max = b
			numMax = 1
		}
	}
	fmt.Println(max-min, numMin*numMax)
}


package main

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

// import bufio, os, strconv
var sc *bufio.Scanner

func scInit() {
	sc = bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
}

func nextInt() int {
	if !sc.Scan() {
		panic("could not scan the reader")
	}
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func nextLong() int64 {
	if !sc.Scan() {
		panic("could not scan the reader")
	}
	i, e := strconv.ParseInt(sc.Text(), 10, 64)
	if e != nil {
		panic(e)
	}
	return i
}

func main() {
	scInit()
	n := nextInt()
	var numMin, numMax int
	var min, max int64
	numMin, numMax = 0, 0
	min, max = 10000000000, -1
	for i := 0; i < n; i++ {
		b := nextLong()
		if b == min {
			numMin++
		}
		if b < min {
			min = b
			numMin = 1
		}
		if b == max {
			numMax++
		}
		if b > max {
			max = b
			numMax = 1
		}
	}
	fmt.Println(max-min, numMin*numMax)
}


package main

import (
	"fmt"
)

func main() {
	var n int
	fmt.Scan(&n)
	var numMin, numMax int
	var min, max int64
	numMin, numMax = 0, 0
	min, max = 10000000000, -1
	for i := 0; i < n; i++ {
		var b int64
		fmt.Scan(&b)
		if b == min {
			numMin++
		}
		if b < min {
			min = b
			numMin = 1
		}
		if b == max {
			numMax++
		}
		if b > max {
			max = b
			numMax = 1
		}
	}
	fmt.Println(max-min, numMin*numMax)
}


package main

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

// import bufio, os, strconv
var sc *bufio.Scanner

func scInit() {
	sc = bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
}

func nextInt() int {
	if !sc.Scan() {
		panic("could not scan the reader")
	}
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func nextLong() int64 {
	if !sc.Scan() {
		panic("could not scan the reader")
	}
	i, e := strconv.ParseInt(sc.Text(), 10, 64)
	if e != nil {
		panic(e)
	}
	return i
}

func main() {
	scInit()
	n := nextInt()
	var numMin, numMax int64
	var min, max int64
	numMin, numMax = 0, 0
	min, max = 10000000000, -1
	for i := 0; i < n; i++ {
		b := nextLong()
		if b == min {
			numMin++
		}
		if b < min {
			min = b
			numMin = 1
		}
		if b == max {
			numMax++
		}
		if b > max {
			max = b
			numMax = 1
		}
	}
	var z int64
	if max == min {
		z = numMax * (numMax - 1) / 2
	} else {
		z = numMax * numMin
	}
	fmt.Println(max-min, z)
}


package main

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"strconv"
)

var DEBUG = true

func main() {
	defer Flush()
	n, b := readInts(0)
	_ = n
	var minv, minc, maxv, maxc int
	minv = b[0]
	maxv = b[0]
	minc = 1
	maxc = 1

	for i := 1; i < n; i++ {
		v := b[i]
		if maxv <= v {
			if maxv < v {
				maxc = 0
			}
			maxv = v
			maxc++
		}
		if v <= minv {
			if v < minv {
				minc = 0
			}
			minv = v
			minc++
		}
	}

	if minv == maxv {
		println(0, maxc*(maxc-1)/2)
	}

	println(maxv-minv, maxc*minc)

}

// -----------------------------------------------------------------------------

// IO helper functions

// Returns next token from input.  It must be initialized by SetInput()
// before the first call.
var nextToken func() ([]byte, error)
var nextLine func() ([]byte, error)

// Holds a buffer for output.  It must be initialized by SetOutput().
// All IO fucntions (read*() and [e]print*()) should write to OutputWriter
// instead of this.
var OutputBuffer *bufio.Writer

// Holds an io.Writer.  It must be initialized by SetOutput()
var OutputWriter io.Writer

// Set IO functions for interactive input/output.
func SetInteractive(w io.Writer, r io.Reader) {
	SetUnbefferedInput(r)
	OutputBuffer = nil
	OutputWriter = w
}

// Setup OutputBuffer and OutputWriter.
func SetOutput(w io.Writer) {
	OutputBuffer = bufio.NewWriter(w)
	OutputWriter = OutputBuffer
}

// Flushes OutputBuffer
func Flush() {
	if OutputBuffer != nil {
		OutputBuffer.Flush()
	}
}

// Returns true if c is a white space
func IsSpace(c byte) bool {
	switch c {
	case '\t', '\n', '\v', '\f', '\r', ' ':
		return true
	}
	return false
}

func IsNewLine(c byte) bool {
	switch c {
	case '\n', '\r':
		return true
	}
	return false
}

// Setup nextToken with input buffer.
func SetInput(r io.Reader) {
	buf := new(bytes.Buffer)
	var b []byte

	var i int
	rest := func() ([]byte, error) {
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		return b[j:i], nil
	}
	initial := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextToken = rest
		return rest()
	}
	nextToken = initial

	restLn := func() ([]byte, error) {
		for i < len(b) && IsNewLine(b[i]) {
			i++
		}
		if i == len(b) {
			return nil, io.ErrUnexpectedEOF
		}
		j := i
		for i < len(b) && !IsNewLine(b[i]) {
			i++
		}
		return b[j:i], nil
	}

	initialLn := func() ([]byte, error) {
		io.Copy(buf, r)
		b = buf.Bytes()
		nextLine = restLn
		return restLn()
	}
	nextLine = initialLn
}

// Setup nextToken without input buffer.
func SetUnbefferedInput(r io.Reader) {
	buf := bufio.NewReader(r)
	var b []byte

	var i int
	nextToken = func() ([]byte, error) {
		var err error
		if i == len(b) {
			b, err = buf.ReadBytes('\n')
			if err != nil {
				return nil, err
			}
			i = 0
			j := len(b) - 1
			for 0 <= j && IsSpace(b[j]) {
				j--
			}
			b = b[0 : j+1]
		}
		for i < len(b) && IsSpace(b[i]) {
			i++
		}
		j := i
		for i < len(b) && !IsSpace(b[i]) {
			i++
		}
		if i == j {
			return nil, io.ErrUnexpectedEOF
		}
		return b[j:i], nil
	}
}

// -----------------------------------------------------------------------------

// IO functions

// Reads next token and return it as []byte
func readb() []byte {
	b, err := nextToken()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Reads next token and return it as string
func reads() string {
	return string(readb())
}

// Read next line as []byte.  Trailing '\n' will not be included.
// See also comments on readb()
func readbln() []byte {
	b, err := nextLine()
	if err != nil {
		panic(err)
	}
	return b[:len(b):len(b)]
}

// Read next line as string
func readsln() string {
	return string(readbln())
}

// Reads next token and return it as int64
func readll() int64 {
	i, err := strconv.ParseInt(reads(), 10, 64)
	if err != nil {
		panic(err.Error())
	}
	return i
}

// Reads next token and return it as int
func readi() int {
	return int(readll())
}

// Reads next token and return it as float64
func readf() float64 {
	f, err := strconv.ParseFloat(reads(), 64)
	if err != nil {
		panic(err.Error())
	}
	return f
}

// Write args to OutputWriter with the format f
func printf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(OutputWriter, f, args...)
}

// Write args to OutputWriter without format
func println(args ...interface{}) (int, error) {
	return fmt.Fprintln(OutputWriter, args...)
}

// Write args to stderr with the format f
func eprintf(f string, args ...interface{}) (int, error) {
	return fmt.Fprintf(os.Stderr, f, args...)
}

// Write args to stderr without format
func eprintln(args ...interface{}) (int, error) {
	return fmt.Fprintln(os.Stderr, args...)
}

func dbgf(f string, args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintf(os.Stderr, f, args...)
}

func dbg(args ...interface{}) {
	if !DEBUG {
		return
	}
	fmt.Fprintln(os.Stderr, args...)
}

// -----------------------------------------------------------------------------

// Utilities

func sumSlice(a []int) int {
	var res int
	for _, v := range a {
		res += v
	}
	return res
}

func sumSlicell(a []int64) int64 {
	var res int64
	for _, v := range a {
		res += v
	}
	return res
}

func readInts(N int) (int, []int) {
	if N == 0 {
		N = readi()
	}
	a := make([]int, N)
	for i := range a {
		a[i] = readi()
	}
	return N, a
}

func readIntsll(N int) (int, []int64) {
	if N == 0 {
		N = readi()
	}
	a := make([]int64, N)
	for i := range a {
		a[i] = readll()
	}
	return N, a
}

// -----------------------------------------------------------------------------

// Simple math functions

const (
	// big prime
	INF  = 1000000007
	INF2 = 1000000009
	INF3 = 998244353
)

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func minll(a, b int64) int64 {
	if a < b {
		return a
	}
	return b
}

func minf(a, b float64) float64 {
	if a < b {
		return a
	}
	return b
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func maxll(a, b int64) int64 {
	if a < b {
		return b
	}
	return a
}

func maxf(a, b float64) float64 {
	if a < b {
		return b
	}
	return a
}

func abs(a int) int {
	if a < 0 {
		return -a
	}
	return a
}

func absll(a int64) int64 {
	if a < 0 {
		return -a
	}
	return a
}

func absf(a float64) float64 {
	if a < 0 {
		return -a
	}
	return a
}

// egcd(a, b) returns d, x, y:
//   d is gcd(a,b)
//   x, y are  integers that satisfy ax + by = d
func egcd(a, b int) (int, int, int) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcd(b, a%b)
	return d, y, x - a/b*y
}

func egcdll(a, b int64) (int64, int64, int64) {
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := egcdll(b, a%b)
	return d, y, x - a/b*y
}

func gcd(a, b int) int {
	d, _, _ := egcd(a, b)
	return d
}

func gcdll(a, b int64) int64 {
	d, _, _ := egcdll(a, b)
	return d
}

// set up IO functions
func init() {
	// for non-interactive
	SetInput(os.Stdin)
	SetOutput(os.Stdout)

	// Enable below when interactive.  Its ok to leave above intact.
	// SetInteractive(os.Stdout, os.Stdin)
}