#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define ll long long
#define rep(i,n) for(ll i=0;i<(n);i++)
#define max(p,q) ((p)>(q)?(p):(q))
#define min(p,q) ((p)<(q)?(p):(q))
#define chmax(a,b) ((a)=(a)>(b)?(a):(b))
#define chmin(a,b) ((a)=(a)<(b)?(a):(b))
#define abs(p) ((p)>=(0)?(p):(-(p)))
#define swap(a,b) do{ll w=(a);(a)=(b);(b)=w;}while(0)
#define swapd(a,b) do{double w=(a);(a)=(b);(b)=w}while(0)
#define in(a) scanf("%lld", &(a))
#define in2(a,b) scanf("%lld %lld",&(a),&(b))
#define in3(a,b,c) scanf("%lld %lld %lld",&(a),&(b),&(c))
#define ind(a) scanf("%lf", &(a))
#define ins(a) scanf("%s", (a))
#define put(a) printf("%lld\n", (a))
#define putd(a) printf("%.15f\n", (a))
//      puts(a) printf("%s\n", a) 文字はこっち
#define MOD 1000000007
ll powll(ll a,ll b){ll r=1;rep(i,b){r*=a;}return r;}
//your code here!
//がっつり解説をみて実装（泣）

//優先度付きキュー　　最大値を求める場合
#define MAX_HEAP 100100
ll heap[MAX_HEAP];
ll heap_idx = -1;
ll PQ_pop(void){//最大値を取り出す。その最大値は削除される
    if(heap_idx<0){                 //空っぽかどうか確認
        puts("Queue has no data");
        exit(1);
    }
    ll i, j, ret = heap[0];         //返り値を保存
    heap[0] = heap[heap_idx--];     //末端の要素を根に移す
    i = 0;                          //根の要素を適当な位置に下げる
    while(i*2+1<=heap_idx){         //子供が存在する条件
        j = i*2+1;
        if(j+1<=heap_idx && heap[j]<heap[j+1]){//min ならここを変更
            j++;
        }
        if(heap[i] >= heap[j]){           //min ならここを変更
            break;
        }
        swap(heap[i],heap[j]);
        i = j;
    }
    return ret;
}
void PQ_push(ll elem){//ヒープに要素elemを追加する
    if(heap_idx >= MAX_HEAP-1){
        puts("Queue has no room");
        exit(1);
    }
    heap[++heap_idx] = elem;
    ll t = heap_idx;
    while(t>0 && heap[(t-1)/2]<heap[t]){//min ならここを変更
        swap(heap[(t-1)/2], heap[t]);
        t = (t-1)/2;
    }
}
//最小を求める場合
ll PQ_pop2(void){//最小値を取り出す。
    if(heap_idx<0){                 //空っぽかどうか確認
        puts("Queue has no data");
        exit(1);
    }
    ll i, j, ret = heap[0];         //返り値を保存
    heap[0] = heap[heap_idx--];     //末端の要素を根に移す
    i = 0;                          //根の要素を適当な位置に下げる
    while(i*2+1<=heap_idx){         //子供が存在する条件
        j = i*2+1;
        if(j+1<=heap_idx && heap[j]>heap[j+1]){//min ならここを変更
            j++;
        }
        if(heap[i] <= heap[j]){           //min ならここを変更
            break;
        }
        swap(heap[i],heap[j]);
        i = j;
    }
    return ret;
}
void PQ_push2(ll elem){//ヒープに要素elemを追加する
    if(heap_idx >= MAX_HEAP-1){
        puts("Queue has no room");
        exit(1);
    }
    heap[++heap_idx] = elem;
    ll t = heap_idx;                    //末端の要素を適当な位置に上げる
    while(t>0 && heap[(t-1)/2]>heap[t]){//min ならここを変更
        swap(heap[(t-1)/2], heap[t]);
        t = (t-1)/2;
    }
}

int main(void){
    ll N, A[300100], ans=-1e15;
    in(N);
    rep(i,3*N) in(A[i]);

    ll score[2][100100];//0行目に a'の前半N要素　1行目に後半N要素　0～Nまで
    //kをN～2Nまでインクリメント。各kでのscoreをmaxにしたい
    //queueの最小値をpopしたい
    score[0][0] = 0;
    rep(i, N){           //O(N*logN)
        PQ_push2(A[i]);
        score[0][0] += A[i];
    }
    rep(k, N){           //O(N*logN)
        score[0][1+k] = score[0][k];//最適な結果を引き継ぐ
        score[0][1+k] += A[N+k];
        PQ_push2(A[k+N]);
        score[0][1+k] -= PQ_pop2();
    }

    //queueをリセット
    heap_idx = -1;

    //各kでのscoreをminにしたい
    //queueの最大値をpopしたい
    ll end = 3*N-1;
    score[1][N] = 0;
    rep(i, N){
        score[1][N] += A[end - i];
        PQ_push(A[end - i]);
    }
    rep(k, N){
        score[1][N-1-k] = score[1][N-k];
        score[1][N-1-k] += A[end-N-k];
        PQ_push(A[end-N-k]);
        score[1][N-1-k] -= PQ_pop();
    }

    //最大値を見つける
    rep(i, N+1) chmax(ans, score[0][i]-score[1][i]);
    put(ans);
    return 0;
}


Measured memory_bytes: 4864