//Jakub Staroń
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <unordered_map>
#include <unordered_set>

#include "message.h"
#include "kanapka.h"

#ifdef COMPILING_HOME
#define DEBUG_MODE
#endif

using namespace std;

typedef char int8;
typedef unsigned char uint8;
typedef short int int16;
typedef unsigned short int uint16;
typedef int int32;
typedef unsigned int uint32;
typedef long long int64;
typedef unsigned long long uint64;

typedef std::pair <int32, int32> int32_pair;
typedef std::pair <uint32, uint32> uint32_pair;
typedef std::pair <int64, int64> int64_pair;
typedef std::pair <uint64, uint64> uint64_pair;

typedef std::vector<bool> bit_vector;

#ifdef DEBUG_MODE
#define debug_print(x) cerr << #x << " = " << x << endl
#define print_line cerr << "Line " << __LINE__ << endl
#include <cassert>
#else
#define debug_print(x)
#define print_line
#define assert(x)
#endif

#define rep(i, x) for(int32 i = 0 ; i < (x) ; i++)
#define for_range(i, begin, end) for(auto i = (begin) ; i != (end) ; ++i )
#define all(c) (c).begin(),(c).end()
#define sort_all(x) sort( all(x) )
#define divide(a, b) ( ( (b)%(a) ) == 0 )
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)

#define sig(x) ( (x) == 0 ? 0 : ( (x) < 0 ? -1 : 1 ) )

const double epsilon = 1e-5;

template<class T>
void unique(std::vector <T> &v) {
    sort_all(v);
    v.resize(std::unique(all(v)) - v.begin());
}

ostream &newline(ostream &str) {
    str.put('\n');
    return str;
}

template<typename T1, typename T2>
istream &operator>>(istream &stream, std::pair <T1, T2> &pair) {
    stream >> pair.first >> pair.second;
    return stream;
}

template<typename T1, typename T2>
ostream &operator<<(ostream &stream, const std::pair <T1, T2> &pair) {
#ifdef DEBUG_MODE
    stream << "(" << pair.first << ", " << pair.second << ")";
#else
    stream << pair.first << ' ' << pair.second;
#endif
    return stream;
}

template<class T>
inline pair <T, T> operator+(const pair <T, T> &a, const pair <T, T> &b) {
    return pair<T, T>(a.first + b.first, a.second + b.second);
}

template<class T>
inline pair <T, T> operator-(const pair <T, T> &a, const pair <T, T> &b) {
    return pair<T, T>(a.first - b.first, a.second - b.second);
}

template<class T>
ostream &operator<<(ostream &str, const vector <T> &v) {
    if (!v.empty()) {
        for (int32 i = 0; i + 1 < v.size(); i++)
            str << v[i] << ' ';
        str << v.back();
    }
    return str;
}

class Graf {
public:
    typedef vector <uint32> list_type;

    void resize(uint32 k) {
        graf.resize(k);
    }

    void add(uint32 a, uint32 b) {
        graf[a].push_back(b);
        graf[b].push_back(a);
    }

    uint32 deg(uint32 k) {
        return graf[k].size();
    }

    list_type &obok(uint32 k) {
        return graf[k];
    }

    uint32 size() {
        return graf.size();
    }

private:
    vector <list_type> graf;
};

const int64 infinity = 1000000000000000000LL;

class Application {
public:
    Application() {
    }

    void Run() {
        WczytajDane();

        if (myNodeId == 0)
            Master();
        else
            Slave();
    }

    void Master() {
        uint64 number = numberOfNodes - 1;
        vector <int64> sum(number);
        vector <int64> max_prefix(number);
        vector <int64> max_suffix(number);
        vector <int64> max_prefix_suffix_sum(number);

        rep(i, number) {
            int32 id = Receive(-1);
            int32 index = id - 1;
            sum[index] = GetLL(id);
            max_prefix[index] = GetLL(id);
            max_suffix[index] = GetLL(id);
            max_prefix_suffix_sum[index] = GetLL(id);
        }

        int64 sum_of_all = 0;
        for(int64 k : sum)
            sum_of_all += k;

        int64 best_result = -infinity;
        rep(begin, number) {
            for_range(end, begin, number) {
                int64 result;
                if (begin == end) {
                    result = sum_of_all - sum[begin] + max_prefix_suffix_sum[begin];
                }
                else {
                    result = 0;
                    for_range(i, 0, begin)
                        result += sum[i];

                    for_range(i, end + 1, number)
                        result += sum[i];

                    result += max_prefix[begin];
                    result += max_suffix[end];
                }
                if (result > best_result)
                    best_result = result;
            }
        }
        cout << best_result << newline;
    }

    void Slave() {
        uint64 number = numberOfNodes - 1;
        uint64 myId = myNodeId - 1;

        uint64 step = (N + number - 1) / number;
        uint64 begin = step * myId;
        uint64 end = min(step * (myId + 1), N);

        vector <int64> V(step);
        rep(i, step)
            V[i] = GetTaste(i + begin);

        vector <int64> prefixes(step + 1);
        vector <int64> suffixes(step + 1);

        rep(i, step) {
            prefixes[i + 1] = prefixes[i] + V[i];
            suffixes[i + 1] = suffixes[i] + V[step - i - 1];
        }

        int64 sum = prefixes.back();
        int64 max_prefix = *max_element(all(prefixes));
        int64 max_suffix = *max_element(all(suffixes));

        int64 max_prefix_suffix_sum = -infinity;
        {
            int64 max_prefix = prefixes[0];
            rep(i, step + 1) {
                max_prefix = max(max_prefix, prefixes[i]);
                int64 sum = suffixes[step - i] + max_prefix;
                if (sum > max_prefix_suffix_sum)
                    max_prefix_suffix_sum = sum;
            }
        }

        PutLL(0, sum);
        PutLL(0, max_prefix);
        PutLL(0, max_suffix);
        PutLL(0, max_prefix_suffix_sum);
        Send(0);
    }

    void WczytajDane() {
        numberOfNodes = NumberOfNodes();
        myNodeId = MyNodeId();
        N = GetN();
    }

    uint64 numberOfNodes;
    uint64 myNodeId;
    uint64 N;
};


int main() {
    ios::sync_with_stdio(0);
    Application application;
    application.Run();
    return 0;
}