#include <bits/stdc++.h>
using namespace std;
template <typename T, typename F>
struct SEGMENT_TREE {
  long long Li, Ri;
  long long pt = 0;
  vector<T> ST;
  vector<long long> L;
  vector<long long> R;
  vector<bool> lazy;
  void new_node() {
    ST.push_back(T{});
    L.push_back(0);
    R.push_back(0);
    lazy.push_back(false);
  }
  SEGMENT_TREE(long long a, long long b) {
    assert(a <= b);
    Li = a, Ri = b;
    new_node();
  }
  void build(vector<T> &vect) {
    assert(Ri - Li + 1 == (long long)vect.size());
    ST_build(0, Li, Ri, vect);
  }
  void insert(long long x, T nod) { ST_insert(0, Li, Ri, x, nod); }
  void update(long long x, F &up) { ST_update(0, Li, Ri, x, x, up); }
  void update(long long a, long long b, F &up) {
    ST_update(0, Li, Ri, a, b, up);
  }
  T query(long long x) { return ST_query(0, Li, Ri, x, x); }
  T query(long long a, long long b) { return ST_query(0, Li, Ri, a, b); }
  void ST_build(long long node, long long l, long long r, vector<T> &vect) {
    if (l == r) {
      ST[node] = vect[l - Li];
      return;
    } else {
      L[node] = ++pt;
      new_node();
      R[node] = ++pt;
      new_node();
    }
    long long mid = (l + r) / 2;
    ST_build(L[node], l, mid, vect);
    ST_build(R[node], mid + 1, r, vect);
    ST[node].merge(ST[L[node]], ST[R[node]]);
  }
  void ST_insert(long long node, long long l, long long r, long long x,
                 T &nod) {
    if (l != r) {
      if (L[node] == 0) {
        L[node] = ++pt;
        new_node();
      }
      if (R[node] == 0) {
        R[node] = ++pt;
        new_node();
      }
    }
    if (lazy[node]) {
      if (l != r) {
        ST[node].propagation(ST[L[node]], ST[R[node]]);
        lazy[L[node]] = true;
        lazy[R[node]] = true;
      }
      ST[node].update(l, r);
      lazy[node] = false;
    }
    if (l == r) {
      ST[node] = nod;
      return;
    }
    long long mid = (l + r) / 2;
    if (x <= mid)
      ST_insert(L[node], l, mid, x, nod);
    else
      ST_insert(R[node], mid + 1, r, x, nod);
    ST[node].merge(ST[L[node]], ST[R[node]]);
  }
  void ST_update(long long node, long long l, long long r, long long a,
                 long long b, F &up) {
    if (l != r) {
      if (L[node] == 0) {
        L[node] = ++pt;
        new_node();
      }
      if (R[node] == 0) {
        R[node] = ++pt;
        new_node();
      }
    }
    if (lazy[node]) {
      if (l != r) {
        ST[node].propagation(ST[L[node]], ST[R[node]]);
        lazy[L[node]] = true;
        lazy[R[node]] = true;
      }
      ST[node].update(l, r);
      lazy[node] = false;
    }
    if (r < a || l > b) return;
    if (a <= l && r <= b) {
      ST[node].push(up);
      if (l != r) {
        ST[node].propagation(ST[L[node]], ST[R[node]]);
        lazy[L[node]] = true;
        lazy[R[node]] = true;
      }
      ST[node].update(l, r);
      return;
    }
    long long mid = (l + r) / 2;
    ST_update(L[node], l, mid, a, b, up);
    ST_update(R[node], mid + 1, r, a, b, up);
    ST[node].merge(ST[L[node]], ST[R[node]]);
  }
  T ST_query(long long node, long long l, long long r, long long a,
             long long b) {
    if (l != r) {
      if (L[node] == 0) {
        L[node] = ++pt;
        new_node();
      }
      if (R[node] == 0) {
        R[node] = ++pt;
        new_node();
      }
    }
    if (lazy[node]) {
      if (l != r) {
        ST[node].propagation(ST[L[node]], ST[R[node]]);
        lazy[L[node]] = true;
        lazy[R[node]] = true;
      }
      ST[node].update(l, r);
      lazy[node] = false;
    }
    if (a <= l && r <= b) {
      return ST[node];
    }
    long long mid = (l + r) / 2;
    T qu;
    bool flag = false;
    if (a <= mid) {
      qu = ST_query(L[node], l, mid, a, b);
      flag = true;
    }
    if (b > mid) {
      T temp = ST_query(R[node], mid + 1, r, a, b);
      if (flag)
        qu.merge(qu, temp);
      else
        swap(qu, temp);
    }
    return qu;
  }
};
struct QUERY {};
struct NODE {
  long long pp = -1e18;
  long long pn = -1e18;
  long long np = -1e18;
  long long nn = -1e18;
  void merge(NODE &H1, NODE &H2) {
    pp = -1e18;
    pn = -1e18;
    np = -1e18;
    nn = -1e18;
    pp = max(pp, H1.pn + H2.pp);
    pp = max(pp, H1.pp + H2.np);
    pp = max(pp, H1.pp);
    pp = max(pp, H2.pp);
    pn = max(pn, H1.pn + H2.pn);
    pn = max(pn, H1.pp + H2.nn);
    pn = max(pn, H1.pn);
    pn = max(pn, H2.pn);
    np = max(np, H1.nn + H2.pp);
    np = max(np, H1.np + H2.np);
    np = max(np, H1.np);
    np = max(np, H2.np);
    nn = max(nn, H1.nn + H2.pn);
    nn = max(nn, H1.np + H2.nn);
    nn = max(nn, H1.nn);
    nn = max(nn, H2.nn);
  }
  void push(QUERY &Q) {}
  void update(long long l, long long r) {}
  void propagation(NODE &H1, NODE &H2) {}
};
const long long MAXN = 3e5 + 100;
long long A[MAXN];
int32_t main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  long long T;
  cin >> T;
  while (T--) {
    long long N, Q;
    cin >> N >> Q;
    SEGMENT_TREE<NODE, QUERY> ST(1, N);
    vector<NODE> vect;
    for (long long i = 1; i <= N; i++) {
      long long n;
      cin >> n;
      NODE tp;
      tp.pp = n;
      tp.nn = -n;
      vect.push_back(tp);
      A[i] = n;
    }
    ST.build(vect);
    cout << max({ST.query(1, N).pp, ST.query(1, N).pn, ST.query(1, N).np,
                 ST.query(1, N).nn})
         << '\n';
    for (long long i = 1; i <= Q; i++) {
      long long a, b;
      cin >> a >> b;
      long long v1 = A[a];
      long long v2 = A[b];
      swap(A[a], A[b]);
      NODE tp1;
      tp1.pp = v1;
      tp1.nn = -v1;
      NODE tp2;
      tp2.pp = v2;
      tp2.nn = -v2;
      ST.insert(a, tp2);
      ST.insert(b, tp1);
      cout << max({ST.query(1, N).pp, ST.query(1, N).pn, ST.query(1, N).np,
                   ST.query(1, N).nn})
           << '\n';
    }
  }
  return 0;
}
