#include <bits/stdc++.h>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <string>
// #include <deque>
// #include <queue>
// #include <array>
// #include <ctime>
// #include <list>
#include <map>
#include <set>
// #include <cassert>
// #include <complex>
// #include <sstream>
// #include <forward_list>
// #include <unordered_set>
// #include <unordered_map>

using namespace std;

#define int long long
#define pb push_back
#define mp make_pair
#define scani(n) scanf("%d",&n);
#define EPS 1e-9
#define FOR(i,n) for(int i=0; i<n; i++)
#define X first
#define Y second
#define arrinput for(int i=0; i<n; i++) cin>>arr[i];
#define arrsum for(int i=0; i<n; i++) sum+=arr[i];
#define for0(i,n) for(int i=0; i<n; i++)
#define for1(i,n) for(int i=1; i<=n; i++)
#define forr(i,n) for(int i=n-1; i>=0; i--)
#define sz(a) (int)(a.size())
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

typedef long long ll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<pii> vii;

const int MOD = 1e9+7;
const int n_ = 1e5+1000;
const long double PI = acos(-1.0);

ll gcd (ll a, ll b) {return ( a ? gcd(b%a, a) : b );}
ll power(ll a, ll n) {ll p = 1;while (n > 0) {if(n%2) {p = p * a;} n >>= 1; a *= a;} return p;}
ll power(ll a, ll n, ll mod) {ll p = 1;while (n > 0) {if(n%2) {p = p * a; p %= mod;} n >>= 1; a *= a; a %= mod;} return p % mod;}

bool vowel(char ch) {
    if(ch=='a' || ch=='e' || ch=='i' || ch=='o' || ch=='u') return true;
    else return false;
}

// Union-Find Disjoint Sets Library written in OOP manner, using both path compression and union by rank heuristics
class UnionFind {                                              // OOP style
private:
    vi p, rank, setSize;                       // remember: vi is vector<int>
    int numSets;
public:
    UnionFind(int N) {
        setSize.assign(N, 1); numSets = N; rank.assign(N, 0);
        p.assign(N, 0); for (int i = 0; i < N; i++) p[i] = i; }
    int findSet(int i) { return (p[i] == i) ? i : (p[i] = findSet(p[i])); }
    bool isSameSet(int i, int j) { return findSet(i) == findSet(j); }
    void unionSet(int i, int j) { 
        if (!isSameSet(i, j)) { numSets--; 
        int x = findSet(i), y = findSet(j);
        // rank is used to keep the tree short
        if (rank[x] > rank[y]) { p[y] = x; setSize[x] += setSize[y]; }
        else                   { p[x] = y; setSize[y] += setSize[x];
                                 if (rank[x] == rank[y]) rank[y]++; } } }
    int numDisjointSets() { return numSets; }
    int sizeOfSet(int i) { return setSize[findSet(i)]; }
};

signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n;
    cin>>n;
    int arr[3*n];
    for0(i,3*n) cin>>arr[i];
    priority_queue<int, vi, greater<int>> pq;
    priority_queue<int> pq1;
    int sum = 0, pre[3*n], suf[3*n];
    for0(i,n) {
        sum += arr[i];
        pq.push(arr[i]);
    }
    pre[n-1] = sum;
    for(int i=n; i<2*n; i++) {
        if(arr[i] > pq.top()) {
            sum -= pq.top();
            pq.pop();
            sum += arr[i];
            pq.push(arr[i]);
        }
        pre[i] = sum;
    }
    sum = 0;
    for(int i=3*n-1; i>=2*n; i--) {
        sum += arr[i];
        pq1.push(arr[i]);
    }
    suf[2*n] = sum;
    for(int i=2*n-1; i>=n; i--) {
        if(arr[i] < pq1.top()) {
            sum -= pq1.top();
            pq1.pop();
            sum += arr[i];
            pq1.push(arr[i]);
        }
        suf[i] = sum;
    }
    int mx = -1*MOD*MOD;
    for(int i=n-1; i<2*n; i++) {
        mx = max(mx, pre[i] - suf[i+1]);
    }
    cout<<mx;

    return 0;
}      

Measured memory_bytes: 8436