#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
struct Seq
{
int s, e;
long long sum;
int prev_seq;
int neg_sum_between;
};
bool CompareSmaller(int a, int b)
{
return a < b;
}
bool CompareGreater(int a, int b)
{
return a > b;
}
class SegTree
{
vector<int> v;
vector<int> tree;
bool(*Comparator)(int, int);
void Build(int node, int left, int right)
{
if (left == right)
{
tree[node] = left;
return;
}
int mid = (left + right) / 2;
int leftc = 2 * node + 1;
int rightc = leftc + 1;
Build(leftc, left, mid);
Build(rightc, mid + 1, right);
if (Comparator(v[tree[leftc]], v[tree[rightc]]))
tree[node] = tree[leftc];
else
tree[node] = tree[rightc];
}
int QueryUtil (int node, int left, int right, int x, int y)
{
if (y < left || x > right)
{
return -1;
}
if (left >= x && right <= y)
return tree[node];
int mid = (left + right) / 2;
int leftc = 2 * node + 1;
int rightc = leftc + 1;
int first = QueryUtil(leftc, left, mid, x, y);
int second = QueryUtil(rightc, mid + 1, right, x, y);
if (first < 0)
return second;
else if (second < 0)
return first;
if (Comparator(v[first], v[second]))
return first;
else
return second;
}
public:
SegTree(vector<int> V, bool(*c)(int, int)) : Comparator(c), v(V), tree(4 * V.size(), 0) { Build(0, 0, V.size() - 1); }
int Query(int x, int y)
{
return QueryUtil(0, 0, v.size() - 1, x, y);
}
};
long long max_sum;
int max_swap_i, max_swap_j;
void UpdateMaxOneSeq(vector<int>& v, SegTree& minTree, SegTree& maxTree, Seq& seq)
{
int min_i_in_seq = minTree.Query(seq.s, seq.e);
if (seq.sum - v[min_i_in_seq] > max_sum)
{
max_sum = seq.sum - v[min_i_in_seq];
max_swap_i = min_i_in_seq;
max_swap_j = seq.s;
}
int max_i_out_seq = -1;
if (0 <= seq.s - 1)
{
int max_i_left_seq = maxTree.Query(0, seq.s - 1);
max_i_out_seq = max_i_left_seq;
}
if (seq.e + 1 <= v.size() - 1)
{
int max_i_right_seq = maxTree.Query(seq.e + 1, v.size() - 1);
if (max_i_out_seq < 0 || v[max_i_right_seq] > v[max_i_out_seq])
{
max_i_out_seq = max_i_right_seq;
}
}
if (max_i_out_seq >= 0 && max_sum < seq.sum - v[min_i_in_seq] + v[max_i_out_seq])
{
max_sum = seq.sum - v[min_i_in_seq] + v[max_i_out_seq];
max_swap_i = min_i_in_seq;
max_swap_j = max_i_out_seq;
}
if (max_i_out_seq >= 0 && max_sum < seq.sum + v[max_i_out_seq])
{
max_sum = seq.sum + v[max_i_out_seq];
max_swap_i = max_i_out_seq;
max_swap_j = seq.s > 0 ? seq.s - 1: seq.e + 1;
}
}
void UpdateMaxTwoSeq(vector<int>& v, SegTree& minTree, SegTree& maxTree, Seq& seq1, Seq& seq2, int neg_sum_between)
{
int min_i_between = minTree.Query(seq1.s + 1, seq2.e - 1);
if (seq1.sum + seq2.sum + neg_sum_between - v[min_i_between] > max_sum)
{
max_sum = seq1.sum + seq2.sum + neg_sum_between - v[min_i_between];
max_swap_i = min_i_between;
max_swap_j = seq1.s;
}
int max_i_out_seq = -1;
if (0 <= seq1.s - 1)
{
int max_i_left_seq = maxTree.Query(0, seq1.s - 1);
max_i_out_seq = max_i_left_seq;
}
if (seq2.e + 1 <= v.size() - 1)
{
int max_i_right_seq = maxTree.Query(seq2.e + 1, v.size() - 1);
if (max_i_out_seq < 0 || v[max_i_right_seq] > v[max_i_out_seq])
{
max_i_out_seq = max_i_right_seq;
}
}
if (max_i_out_seq >= 0 && max_sum < seq1.sum + seq2.sum + neg_sum_between - v[min_i_between] + v[max_i_out_seq])
{
max_sum = seq1.sum + seq2.sum + neg_sum_between - v[min_i_between] + v[max_i_out_seq];
max_swap_i = min_i_between;
max_swap_j = max_i_out_seq;
}
}
int main()
{
int n;
cin >> n;
vector<int> v(n, 0);
for (int i = 0; i < n; i++)
{
cin >> v[i];
}
vector<Seq> seqs;
long long sc = 0;
int ic = 0;
int prev_seq = -1;
int last_pos_i = -1;
int prev_longest_seq_i = -1;
int current_max_sum_seq_i = -1;
long long cur_neg_seq_sum = 0;
long long prev_neg_sum_between = 0;
long long neg_sum_between = 0;
for (int i = 0; i < n; i++)
{
if (i > 0 && v[i] < 0 && v[i - 1] > 0)
{
seqs.push_back({ ic, i - 1, sc, -1, -1 });
if (current_max_sum_seq_i < 0 || sc > seqs[current_max_sum_seq_i].sum)
current_max_sum_seq_i = seqs.size() - 1;
}
if (v[i] < 0)
cur_neg_seq_sum += v[i];
else
cur_neg_seq_sum = 0;
if (sc + v[i] < 0)
{
ic = i + 1;
if (current_max_sum_seq_i >= 0)
{
seqs[current_max_sum_seq_i].prev_seq = prev_longest_seq_i;
seqs[current_max_sum_seq_i].neg_sum_between = neg_sum_between;
prev_longest_seq_i = seqs.size() - 1;
current_max_sum_seq_i = -1;
}
neg_sum_between = cur_neg_seq_sum;
sc = 0;
}
else
{
sc += v[i];
}
}
if (v[v.size() - 1] > 0)
{
seqs.push_back({ ic, (int)v.size() - 1, sc, -1, -1 });
if (current_max_sum_seq_i < 0 || sc > seqs[current_max_sum_seq_i].sum)
current_max_sum_seq_i = seqs.size() - 1;
seqs[current_max_sum_seq_i].prev_seq = prev_longest_seq_i;
seqs[current_max_sum_seq_i].neg_sum_between = neg_sum_between;
prev_longest_seq_i = seqs.size() - 1;
current_max_sum_seq_i = -1;
}
SegTree treeMin(v, CompareSmaller), treeMax(v, CompareGreater);
if (seqs.empty())
{
int poz = max_element(v.begin(), v.end()) - v.begin();
cout << v[poz] << endl << "1 " << poz << endl;
return 0;
}
if (seqs[0].s == 0 && seqs[0].e == v.size() - 1)
{
std::cout << seqs[0].sum << endl << "1 2" << endl;
return 0;
}
for (int i = 0; i < seqs.size(); i++)
{
UpdateMaxOneSeq(v, treeMin, treeMax, seqs[i]);
if (seqs[i].prev_seq >= 0)
{
UpdateMaxTwoSeq(v, treeMin, treeMax, seqs[seqs[i].prev_seq], seqs[i], seqs[i].neg_sum_between);
}
}
cout << max_sum << endl;
cout << max_swap_i + 1 << ' ' << max_swap_j + 1<< endl;
return 0;
}