Problem:
Problem C:
Kuru Kuru Sushi
Zephir is an owner of the kuru kuru sushi restaurants. In these restaurants, sushis are placed
on a rotating circular belt conveyor and delivered to customers.
Zephir owns $n$ restaurants numbered from $0$ to $n - 1$. Due to his passion for rotation, these
restaurants are placed on the circumference of a circle, and have huge belt conveyors under the
ground between adjacent restaurants. One day, the ingredients of sushis were short in some
restaurants. Therefore, he decided to transport some ingredient foods between restaurants by
using these belt conveyors.
The $i$-th ($0 \leq i \leq n - 2$) belt conveyor connects the restaurants $i$ and $i+1$. The ($n - 1$)-th belt
conveyor connects the restaurants $n - 1$ and $0$. The length of the $i$-th belt conveyor is $w_i$. He
wants to transport $q$ foods from some restaurants to other restaurants. The $i$-th food should be
transported from restaurant $s_i$ to $t_i$.
Zephir wants to minimize the total cost of transportation. The transportation cost of each food
can be changed by the settings of the direction of the belt conveyors. Each belt conveyor can
transport foods in only a single direction, which can be set by Zephir. Moreover, the settings
cannot be changed while transporting all $q$ foods. The transportation cost of the $i$-th food is
the sum of the length of the belt conveyors in the shortest path from restaurant $s_i$ to $t_i$. He
should set the direction of belt conveyors to transport all foods. Write a program to calculate
the minimum value of the total cost, which is the sum of the transportation costs of all the $q$
foods.
Input
Each input is formatted as follows:
$n$ $q$
$w_0$ $w_1$ ... $w_{n-1}$
$s_0$ $t_0$
...
$s_{q-1}$ $t_{q-1}$
The first line contains two integers $n$ and $q$. $n$ ($3 \leq n \leq 10^5$) denotes the number of the
restaurants, and $q$ ($1 \leq q \leq 10^5$) denotes the number of the foods to transport. The next line
contains $n$ integers. $w_i$ ($1 \leq w_i \leq 10^5$) denotes the length of the $i$-th belt conveyor. Each of the
following $q$ lines contains two integers $s_i$ ($0 \leq s_i \leq n - 1$) and $t_i$ ($0 \leq t_i \leq n - 1$). Each denotes
the $i$-th food should be transported from restaurant $s_i$ to $t_i$. You may assume $s_i \ne t_i$ for any
$0 \leq i \leq q - 1$, and $s_i \ne s_j$ or $t_i \ne t_j$ if $i \ne j$ for any $0 \leq i, j \leq q - 1$.
Output
Print the minimum total cost of the foods transportation. If it is impossible to transport all
foods to each destination, print -1.
Sample Input
4 4
1 1 1 1
0 1
0 3
2 3
3 0
Output for the Sample Input
6
Sample Input
5 3
4 5 6 7 8
0 1
0 3
4 2
Output for the Sample Input
32

Submitted solutions:

code_snippet: // AOJ #2719 Kuru Kuru Sushi
// 2025.3.25

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) {
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
const int NMAX = 100005;
const int INF = 1001001001;

int n, q;
int w[NMAX];
ll s[NMAX];
pii p[NMAX];
int im[NMAX];

ll segSum(int l, int r) { return s[r] - s[l]; }

ll solve() {
    ll res = 0;
    for (int i = 0; i < n; i++) s[i+1] = s[i] + w[i];
    ll cur = 0;
    for (int i = 0; i < q; i++) {
        if (p[i].first < p[i].second) {
            cur += segSum(0, p[i].first);
            cur += segSum(p[i].second, n);
        } else cur += segSum(p[i].second, p[i].first);
    }
    res = cur;
    cur = 0;

    vector<pii> segs;
    for (int i = 0; i <= n; i++) im[i] = 0;
    for (int i = 0; i < q; i++) {
        if (p[i].first < p[i].second) segs.push_back(p[i]);
        else {
            int L = p[i].second, R = p[i].first;
            cur += segSum(L, R);
            im[L+1]++;
            im[R+1]--;
        }
    }
    for (int i = 0; i < n; i++) im[i+1] += im[i];
    for (int i = 0; i < n; i++) im[i] = (im[i] != 0);
    for (int i = 0; i < n; i++) im[i+1] += im[i];

    int sz = segs.size();
    vector<pii> Ls, Rs;
    for (int i = 0; i < sz; i++) {
        Ls.push_back({segs[i].first, i});
        Rs.push_back({segs[i].second, i});
    }
    sort(Ls.begin(), Ls.end());
    sort(Rs.begin(), Rs.end());
    reverse(Rs.begin(), Rs.end());

    queue<int> que;
    vector<int> used(sz, 0);
    for (int i = 0; i < sz; i++) {
        int L = segs[i].first, R = segs[i].second;
        if (im[R] - im[L]) que.push(i);
    }
    int li = 0, ri = 0;
    while (!que.empty()) {
        int i = que.front();
        que.pop();
        if (used[i]) continue;
        used[i] = 1;
        cur += segSum(0, segs[i].first);
        cur += segSum(segs[i].second, n);
        while (li < sz) {
            int ni = Ls[li].second;
            if (segs[ni].first >= segs[i].first) break;
            que.push(ni);
            li++;
        }
        while (ri < sz) {
            int ni = Rs[ri].second;
            if (segs[ni].second <= segs[i].second) break;
            que.push(ni);
            ri++;
        }
    }

    vector<ll> ac(sz, 0);
    vector<ppi> ev;
    ll best = 0;
    for (int i = 0; i < sz; i++) {
        if (used[i]) continue;
        ll cx = segSum(0, segs[i].first) + segSum(segs[i].second, n);
        ll cy = segSum(segs[i].first, segs[i].second);
        cur += cy;
        ac[i] = cx - cy;
        ev.push_back({{segs[i].first, -segs[i].second}, i});
    }
    vector<int> eds;
    for (int i = 0; i < (int)ev.size(); i++) eds.push_back(ev[i].first.second);
    sort(eds.begin(), eds.end());
    sort(ev.begin(), ev.end());
    ll nst = 0;
    for (int i = 0; i < (int)ev.size(); i++) {
        int idx = ev[i].second;
        if (ev[i].first.second != eds[i]) break;
        nst += ac[idx];
        best = min(best, nst);
    }
    cur += best;
    res = min(res, cur);
    return res;
}

int main(){
    n = Cin(), q = Cin();
    for (int i = 0; i < n; i++) w[i] = Cin();

    for (int i = 0; i < q; i++) {
        int s = Cin(), t = Cin();
        p[i] = {s, t};
    }
    ll ans = solve();
    for (int i = n-1; i >= 0; i--) w[i+1] = w[i];
    w[0] = w[n];
    for (int i = 0; i < q; i++) {
        p[i].first = (p[i].first + 1) % n;
        p[i].second = (p[i].second + 1) % n;
    }
    reverse(w, w + n);
    for (int i = 0; i < q; i++) {
        p[i].first = (n - p[i].first) % n;
        p[i].second = (n - p[i].second) % n;
    }
    ans = min(ans, solve());
    Cout(ans);
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 11108
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
	if(x<y){ x=y; return true; }
	return false;
}
template<class T,class U> bool chmin(T& x, U y){
	if(y<x){ x=y; return true; }
	return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
    return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
  return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ~ ";
	dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {";  \
	for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif

template<class D> D divFloor(D a, D b){
	return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
	return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}
template<class D>
struct lazyseg{
	using S = typename D::Monoid;
	using F = typename D::Action;
	int N;
	vector<S> val;
	vector<F> act;
	lazyseg(){}
	lazyseg(int n){
		N=1;
		while(N<n) N*=2;
		val.assign(N*2,D::e());
		act.assign(N*2,D::id());
	}
	template<class Slike>
	lazyseg(const vector<Slike>& val_){
		int n = val_.size();
		N=1;
		while(N<n) N*=2;
		val .assign(N*2,D::e());
		rep(i,n) val[i+N] = S(val_[i]);
		for(int i=N-1;i>0;i--) val[i] = D::op(val[i*2],val[i*2+1]);
		act.assign(N*2,D::id());
	}

	S query(int a,int b){
		return query(a,b,0,N,1);
	}
	void apply(int i, F f){
		apply(i,i+1,f);
	}
	void apply(int a,int b, F f){
		apply(a,b,f,0,N,1);
	}
	void assign(int i, S x){
		assign(i,i+1,x,0,N,1);
	}

	private:
	S query(int a,int b,int l,int r,int k){
		if(b<=l || r<=a) return D::e();
		if(a<=l && r<=b) return val[k];
		propagate(l,r,k);
		return D::op(query(a,b,l,(l+r)/2,k*2) , query(a,b,(l+r)/2,r,k*2+1));
	}
	void apply(int a,int b,const F& f,int l,int r,int k){
		if(b<=l || r<=a) return;
		if(a<=l && r<=b){
			addlazy(k,f);
			return;
		}
		propagate(l,r,k);
		apply(a,b,f,l,(l+r)/2,k*2);
		apply(a,b,f,(l+r)/2,r,k*2+1);
		val[k] = D::op(val[k*2] , val[k*2+1]);
	}
	void assign(int a,int b,const S& x, int l,int r,int k){
		if(b<=l || r<=a) return;
		if(a<=l && r<=b){
			// l = i, r = i+1
			val[k] = x;
			act[k] = D::id();
			return;
		}
		propagate(l,r,k);
		assign(a,b,x,l,(l+r)/2,k*2);
		assign(a,b,x,(l+r)/2,r,k*2+1);
		val[k] = D::op(val[k*2] , val[k*2+1]);
	}
	void addlazy(int k, const F& f){
		act[k] = D::composite(f,act[k]);		// 上の階層の lazy ( = f) のほうがよりあと
		val[k] = D::act(f,val[k]);				// val は常に正しく
	}

	void propagate(int l,int r,int k){
		addlazy(k*2  , act[k]);
		addlazy(k*2+1, act[k]);
		act[k] = D::id();
	}
};
struct D{
	struct Monoid{
		ll ab,a,b,n;
		Monoid():ab(0),a(0),b(0),n(0){}
		Monoid(int n_):ab(0),a(0),b(0),n(n_){}
	};
	struct Action{
		ll a,b;
		Action(){}
		Action(ll a_, ll b_):a(a_),b(b_){}
	};
	const static Monoid e(){
		return Monoid();
	}
	const static Monoid op(const Monoid& x, const Monoid& y){
		Monoid z;
		z.ab = x.ab+y.ab;
		z.a = x.a+y.a;
		z.b = x.b+y.b;
		z.n = x.n+y.n;
		return z;
	}

	const static Action id(){
		return Action(0,0);
	}
	const static Action composite(const Action& f, const Action& g){
		// f \times g
		Action h;
		h.a = f.a+g.a;
		h.b = f.b+g.b;
		return h;
	}

	const static Monoid act(const Action& f, const Monoid& x){
		Monoid z;
		z.ab = x.ab + x.a*f.b + x.b*f.a + f.a*f.b*x.n;
		z.a = x.a + f.a*x.n;
		z.b = x.b + f.b*x.n;
		z.n = x.n;
		return z;
	}
};
int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	int N,Q; cin >> N >> Q;
	V<ll> w(N); rep(i,N) cin >> w[i];
	V<ll> wa(N+1); rep(i,N) wa[i+1] = wa[i] + w[i];
	VV<int> s2t(N),t2s(N);
	rep(i,Q){
		int s,t; cin >> s >> t;
		s2t[s].pb(t);
		t2s[t].pb(s);
	}
	auto len = [&](int s,int t){
		if(s < t) return wa[t] - wa[s];
		return wa[t] - wa[s] + wa[N];
	};
	const ll inf = TEN(18);
	ll ans = inf;
	rep(d,2){
		ll sum = 0;
		rep(s,N) for(int t: s2t[s]){
			sum += (d == 0 ? len(s,t) : len(t,s));
		}
		chmin(ans,sum);
	}
	struct Waf{
		int x,y,sgn;
	};
	VV<Waf> start(N),end(N);
	rep(s,N) for(int t: s2t[s]){
		start[(s+1)%N].pb({t,s,-1});
		end[t].pb({t,s,-1});
		start[(t+1)%N].pb({s,t,1});
		end[s].pb({s,t,1});
	}

	using S = D::Monoid;
	using F = D::Action;
	lazyseg<D> seg(V<int>(N,1));
	multiset<int> red,blue;
	ll cost = 0;

	auto Addpos = [&](int x,int y,int v){
		cost += len(x,y) * v;
		F f(v,0);
		if(x < y){
			seg.apply(x,y,f);
		}else{
			seg.apply(x,N,f);
			seg.apply(0,y,f);
		}
		if(v == 1) red.insert(y);
		else{
			auto it = red.lower_bound(y);
			assert(*it == y);
			red.erase(it);
		}
	};
	auto Addneg = [&](int x,int y,int v){
		cost += len(x,y) * v;
		F f(0,v);
		if(x < y){
			seg.apply(x,y,f);
		}else{
			seg.apply(x,N,f);
			seg.apply(0,y,f);
		}
		if(v == 1) blue.insert(x);
		else{
			auto it = blue.lower_bound(x);
			assert(*it == x);
			blue.erase(it);
		}
	};
	rep(x,N){
		if(x == 0){
			rep(s,N) for(int t: s2t[s]){
				if(s != 0 && t != 0){
					if(s < t){
						Addpos(s,t,1);
					}else{
						Addneg(t,s,1);
					}
				}
			}
		}else{
			for(auto w: start[x]){
				if(w.sgn == 1) Addpos(w.x,w.y,1);
				else Addneg(w.x,w.y,1);
			}
			for(auto w: end[x]){
				if(w.sgn == 1) Addpos(w.x,w.y,-1);
				else Addneg(w.x,w.y,-1);
			}
		}
		if(!t2s[x].empty()) continue;
		if(seg.query(0,N).ab != 0) continue;
		int R = -1;
		if(!red.empty()){
			auto it = red.lower_bound(x);
			if(it == red.begin()){
				R = *red.rbegin();
			}else{
				it--;
				R = *it;
			}
		}
		int B = -1;
		if(!blue.empty()){
			auto it = blue.lower_bound(x);
			if(it == blue.end()){
				B = *blue.begin();
			}else{
				B = *it;
			}
		}
		ll tmp = cost;
		auto between = [&](int l, int x, int r){
			if(l < r) return l<=x && x<=r;
			return l<=x || x<=r;
		};
		for(int t: s2t[x]){
			ll c = inf;
			if(R == -1 or between(R,t,x)) chmin(c,len(t,x));
			if(B == -1 or between(x,t,B)) chmin(c,len(x,t));
			if(c == inf) tmp = inf;
			else tmp += c;
		}
		chmin(ans,tmp);
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 390
memory_kb: 43136
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
	if(x<y){ x=y; return true; }
	return false;
}
template<class T,class U> bool chmin(T& x, U y){
	if(y<x){ x=y; return true; }
	return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
    return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
  return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ~ ";
	dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {";  \
	for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif

template<class D> D divFloor(D a, D b){
	return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
	return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}
template<class D>
struct lazyseg{
	using S = typename D::Monoid;
	using F = typename D::Action;
	int N;
	vector<S> val;
	vector<F> act;
	lazyseg(){}
	lazyseg(int n){
		N=1;
		while(N<n) N*=2;
		val.assign(N*2,D::e());
		act.assign(N*2,D::id());
	}
	template<class Slike>
	lazyseg(const vector<Slike>& val_){
		int n = val_.size();
		N=1;
		while(N<n) N*=2;
		val .assign(N*2,D::e());
		rep(i,n) val[i+N] = S(val_[i]);
		for(int i=N-1;i>0;i--) val[i] = D::op(val[i*2],val[i*2+1]);
		act.assign(N*2,D::id());
	}

	S query(int a,int b){
		return query(a,b,0,N,1);
	}
	void apply(int i, F f){
		apply(i,i+1,f);
	}
	void apply(int a,int b, F f){
		apply(a,b,f,0,N,1);
	}
	void assign(int i, S x){
		assign(i,i+1,x,0,N,1);
	}

	private:
	S query(int a,int b,int l,int r,int k){
		if(b<=l || r<=a) return D::e();
		if(a<=l && r<=b) return val[k];
		propagate(l,r,k);
		return D::op(query(a,b,l,(l+r)/2,k*2) , query(a,b,(l+r)/2,r,k*2+1));
	}
	void apply(int a,int b,const F& f,int l,int r,int k){
		if(b<=l || r<=a) return;
		if(a<=l && r<=b){
			addlazy(k,f);
			return;
		}
		propagate(l,r,k);
		apply(a,b,f,l,(l+r)/2,k*2);
		apply(a,b,f,(l+r)/2,r,k*2+1);
		val[k] = D::op(val[k*2] , val[k*2+1]);
	}
	void assign(int a,int b,const S& x, int l,int r,int k){
		if(b<=l || r<=a) return;
		if(a<=l && r<=b){
			// l = i, r = i+1
			val[k] = x;
			act[k] = D::id();
			return;
		}
		propagate(l,r,k);
		assign(a,b,x,l,(l+r)/2,k*2);
		assign(a,b,x,(l+r)/2,r,k*2+1);
		val[k] = D::op(val[k*2] , val[k*2+1]);
	}
	void addlazy(int k, const F& f){
		act[k] = D::composite(f,act[k]);		// 上の階層の lazy ( = f) のほうがよりあと
		val[k] = D::act(f,val[k]);				// val は常に正しく
	}

	void propagate(int l,int r,int k){
		addlazy(k*2  , act[k]);
		addlazy(k*2+1, act[k]);
		act[k] = D::id();
	}
};
struct D{
	struct Monoid{
		ll ab,a,b,n;
		Monoid():ab(0),a(0),b(0),n(0){}
		Monoid(int n_):ab(0),a(0),b(0),n(n_){}
	};
	struct Action{
		ll a,b;
		Action(){}
		Action(ll a_, ll b_):a(a_),b(b_){}
	};
	const static Monoid e(){
		return Monoid();
	}
	const static Monoid op(const Monoid& x, const Monoid& y){
		Monoid z;
		z.ab = x.ab+y.ab;
		z.a = x.a+y.a;
		z.b = x.b+y.b;
		z.n = x.n+y.n;
		return z;
	}

	const static Action id(){
		return Action(0,0);
	}
	const static Action composite(const Action& f, const Action& g){
		// f \times g
		Action h;
		h.a = f.a+g.a;
		h.b = f.b+g.b;
		return h;
	}

	const static Monoid act(const Action& f, const Monoid& x){
		Monoid z;
		z.ab = x.ab + x.a*f.b + x.b*f.a + f.a*f.b*x.n;
		z.a = x.a + f.a*x.n;
		z.b = x.b + f.b*x.n;
		z.n = x.n;
		return z;
	}
};
int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	int N,Q; cin >> N >> Q;
	V<ll> w(N); rep(i,N) cin >> w[i];
	V<ll> wa(N+1); rep(i,N) wa[i+1] = wa[i] + w[i];
	VV<int> s2t(N),t2s(N);
	rep(i,Q){
		int s,t; cin >> s >> t;
		s2t[s].pb(t);
		t2s[t].pb(s);
	}
	auto len = [&](int s,int t){
		if(s < t) return wa[t] - wa[s];
		return wa[t] - wa[s] + wa[N];
	};
	const ll inf = TEN(18);
	ll ans = inf;
	rep(d,2){
		ll sum = 0;
		rep(s,N) for(int t: s2t[s]){
			sum += (d == 0 ? len(s,t) : len(t,s));
		}
		chmin(ans,sum);
	}
	struct Waf{
		int x,y,sgn;
	};
	VV<Waf> start(N),end(N);
	rep(s,N) for(int t: s2t[s]){
		start[(s+1)%N].pb({t,s,-1});
		end[t].pb({t,s,-1});
		start[(t+1)%N].pb({s,t,1});
		end[s].pb({s,t,1});
	}

	using S = D::Monoid;
	using F = D::Action;
	lazyseg<D> seg(V<int>(N,1));
	multiset<int> red,blue;
	ll cost = 0;

	auto Addpos = [&](int x,int y,int v){
		cost += len(x,y) * v;
		F f(v,0);
		if(x < y){
			seg.apply(x,y,f);
		}else{
			seg.apply(x,N,f);
			seg.apply(0,y,f);
		}
		if(v == 1) red.insert(y);
		else{
			auto it = red.lower_bound(y);
			assert(*it == y);
			red.erase(it);
		}
	};
	auto Addneg = [&](int x,int y,int v){
		cost += len(x,y) * v;
		F f(0,v);
		if(x < y){
			seg.apply(x,y,f);
		}else{
			seg.apply(x,N,f);
			seg.apply(0,y,f);
		}
		if(v == 1) blue.insert(x);
		else{
			auto it = blue.lower_bound(x);
			assert(*it == x);
			blue.erase(it);
		}
	};
	rep(x,N){
		if(x == 0){
			rep(s,N) for(int t: s2t[s]){
				if(s != 0 && t != 0){
					if(s < t){
						Addpos(s,t,1);
					}else{
						Addneg(t,s,1);
					}
				}
			}
		}else{
			for(auto w: start[x]){
				if(w.sgn == 1) Addpos(w.x,w.y,1);
				else Addneg(w.x,w.y,1);
			}
			for(auto w: end[x]){
				if(w.sgn == 1) Addpos(w.x,w.y,-1);
				else Addneg(w.x,w.y,-1);
			}
		}
		if(!t2s[x].empty()) continue;
		if(seg.query(0,N).ab != 0) continue;
		int R = -1;
		if(!red.empty()){
			auto it = red.lower_bound(x);
			if(it == red.begin()){
				R = *red.rend();
			}else{
				it--;
				R = *it;
			}
		}
		int B = -1;
		if(!blue.empty()){
			auto it = blue.lower_bound(x);
			if(it == blue.end()){
				B = *blue.begin();
			}else{
				B = *it;
			}
		}
		ll tmp = cost;
		auto between = [&](int l, int x, int r){
			if(l < r) return l<=x && x<=r;
			return l<=x || x<=r;
		};
		for(int t: s2t[x]){
			ll c = inf;
			if(R == -1 or between(R,t,x)) chmin(c,len(t,x));
			if(B == -1 or between(x,t,B)) chmin(c,len(x,t));
			if(c == inf) tmp = inf;
			else tmp += c;
		}
		chmin(ans,tmp);
	}
	cout << ans << endl;
}
accuracy: 0.6120689655172413
time_ms: 390
memory_kb: 41624
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
	if(x<y){ x=y; return true; }
	return false;
}
template<class T,class U> bool chmin(T& x, U y){
	if(y<x){ x=y; return true; }
	return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
    return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
  return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
	os<<t<<" ~ ";
	dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {";  \
	for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif

template<class D> D divFloor(D a, D b){
	return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
	return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}
template<class D>
struct lazyseg{
	using S = typename D::Monoid;
	using F = typename D::Action;
	int N;
	vector<S> val;
	vector<F> act;
	lazyseg(){}
	lazyseg(int n){
		N=1;
		while(N<n) N*=2;
		val.assign(N*2,D::e());
		act.assign(N*2,D::id());
	}
	template<class Slike>
	lazyseg(const vector<Slike>& val_){
		int n = val_.size();
		N=1;
		while(N<n) N*=2;
		val .assign(N*2,D::e());
		rep(i,n) val[i+N] = S(val_[i]);
		for(int i=N-1;i>0;i--) val[i] = D::op(val[i*2],val[i*2+1]);
		act.assign(N*2,D::id());
	}

	S query(int a,int b){
		return query(a,b,0,N,1);
	}
	void apply(int i, F f){
		apply(i,i+1,f);
	}
	void apply(int a,int b, F f){
		apply(a,b,f,0,N,1);
	}
	void assign(int i, S x){
		assign(i,i+1,x,0,N,1);
	}

	private:
	S query(int a,int b,int l,int r,int k){
		if(b<=l || r<=a) return D::e();
		if(a<=l && r<=b) return val[k];
		propagate(l,r,k);
		return D::op(query(a,b,l,(l+r)/2,k*2) , query(a,b,(l+r)/2,r,k*2+1));
	}
	void apply(int a,int b,const F& f,int l,int r,int k){
		if(b<=l || r<=a) return;
		if(a<=l && r<=b){
			addlazy(k,f);
			return;
		}
		propagate(l,r,k);
		apply(a,b,f,l,(l+r)/2,k*2);
		apply(a,b,f,(l+r)/2,r,k*2+1);
		val[k] = D::op(val[k*2] , val[k*2+1]);
	}
	void assign(int a,int b,const S& x, int l,int r,int k){
		if(b<=l || r<=a) return;
		if(a<=l && r<=b){
			// l = i, r = i+1
			val[k] = x;
			act[k] = D::id();
			return;
		}
		propagate(l,r,k);
		assign(a,b,x,l,(l+r)/2,k*2);
		assign(a,b,x,(l+r)/2,r,k*2+1);
		val[k] = D::op(val[k*2] , val[k*2+1]);
	}
	void addlazy(int k, const F& f){
		act[k] = D::composite(f,act[k]);		// 上の階層の lazy ( = f) のほうがよりあと
		val[k] = D::act(f,val[k]);				// val は常に正しく
	}

	void propagate(int l,int r,int k){
		addlazy(k*2  , act[k]);
		addlazy(k*2+1, act[k]);
		act[k] = D::id();
	}
};
struct D{
	struct Monoid{
		ll ab,a,b,n;
		Monoid():ab(0),a(0),b(0),n(0){}
		Monoid(int n_):ab(0),a(0),b(0),n(n_){}
	};
	struct Action{
		ll a,b;
		Action(){}
		Action(ll a_, ll b_):a(a_),b(b_){}
	};
	const static Monoid e(){
		return Monoid();
	}
	const static Monoid op(const Monoid& x, const Monoid& y){
		Monoid z;
		z.ab = x.ab+y.ab;
		z.a = x.a+y.a;
		z.b = x.b+y.b;
		z.n = x.n+y.n;
		return z;
	}

	const static Action id(){
		return Action(0,0);
	}
	const static Action composite(const Action& f, const Action& g){
		// f \times g
		Action h;
		h.a = f.a+g.a;
		h.b = f.b+g.b;
		return h;
	}

	const static Monoid act(const Action& f, const Monoid& x){
		Monoid z;
		z.ab = x.ab + x.a*f.b + x.b*f.a + f.a*f.b*x.n;
		z.a = x.a + f.a;
		z.b = x.b + f.b;
		z.n = x.n;
		return z;
	}
};
int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);		//DON'T USE scanf/printf/puts !!
	cout << fixed << setprecision(20);

	int N,Q; cin >> N >> Q;
	V<ll> w(N); rep(i,N) cin >> w[i];
	V<ll> wa(N+1); rep(i,N) wa[i+1] = wa[i] + w[i];
	VV<int> s2t(N),t2s(N);
	rep(i,Q){
		int s,t; cin >> s >> t;
		s2t[s].pb(t);
		t2s[t].pb(s);
	}
	auto len = [&](int s,int t){
		if(s < t) return wa[t] - wa[s];
		return wa[t] - wa[s] + wa[N];
	};
	const ll inf = TEN(18);
	ll ans = inf;
	rep(d,2){
		ll sum = 0;
		rep(s,N) for(int t: s2t[s]){
			sum += (d == 0 ? len(s,t) : len(t,s));
		}
		chmin(ans,sum);
	}
	struct Waf{
		int x,y,sgn;
	};
	VV<Waf> start(N),end(N);
	rep(s,N) for(int t: s2t[s]){
		start[(s+1)%N].pb({t,s,-1});
		end[t].pb({t,s,-1});
		start[(t+1)%N].pb({s,t,1});
		end[s].pb({s,t,1});
	}

	using S = D::Monoid;
	using F = D::Action;
	lazyseg<D> seg(V<int>(N,1));
	multiset<int> red,blue;
	ll cost = 0;

	auto Addpos = [&](int x,int y,int v){
		cost += len(x,y) * v;
		F f(v,0);
		if(x < y){
			seg.apply(x,y,f);
		}else{
			seg.apply(x,N,f);
			seg.apply(0,y,f);
		}
		if(v == 1) red.insert(y);
		else{
			auto it = red.lower_bound(y);
			assert(*it == y);
			red.erase(it);
		}
	};
	auto Addneg = [&](int x,int y,int v){
		cost += len(x,y) * v;
		F f(0,v);
		if(x < y){
			seg.apply(x,y,f);
		}else{
			seg.apply(x,N,f);
			seg.apply(0,y,f);
		}
		if(v == 1) blue.insert(x);
		else{
			auto it = blue.lower_bound(x);
			assert(*it == x);
			blue.erase(it);
		}
	};
	rep(x,N){
		if(x == 0){
			rep(s,N) for(int t: s2t[s]){
				if(s != 0 && t != 0){
					if(s < t){
						Addpos(s,t,1);
					}else{
						Addneg(t,s,1);
					}
				}
			}
		}else{
			for(auto w: start[x]){
				if(w.sgn == 1) Addpos(w.x,w.y,1);
				else Addneg(w.x,w.y,1);
			}
			for(auto w: end[x]){
				if(w.sgn == 1) Addpos(w.x,w.y,-1);
				else Addneg(w.x,w.y,-1);
			}
		}
		if(!t2s[x].empty()) continue;
		if(seg.query(0,N).ab != 0) continue;
		int R = -1;
		if(!red.empty()){
			auto it = red.lower_bound(x);
			if(it == red.begin()){
				R = *red.rend();
			}else{
				it--;
				R = *it;
			}
		}
		int B = -1;
		if(!blue.empty()){
			auto it = blue.lower_bound(x);
			if(it == blue.end()){
				B = *blue.begin();
			}else{
				B = *it;
			}
		}
		ll tmp = cost;
		auto between = [&](int l, int x, int r){
			if(l < r) return l<=x && x<=r;
			return l<=x || x<=r;
		};
		for(int t: s2t[x]){
			ll c = inf;
			if(R == -1 or between(R,t,x)) chmin(c,len(t,x));
			if(B == -1 or between(x,t,B)) chmin(c,len(x,t));
			if(c == inf) tmp = inf;
			else tmp += c;
		}
		chmin(ans,tmp);
	}
	cout << ans << endl;
}
accuracy: 0.017241379310344827
time_ms: 220
memory_kb: 37360
final_rank: 4