import java.io.*;
import java.util.*;
public class Main {
static final class FastScanner {
private final InputStream in = System.in;
private final byte[] buffer = new byte[1 << 16];
private int ptr = 0, len = 0;
private int read() throws IOException {
if (ptr >= len) {
len = in.read(buffer);
ptr = 0;
if (len <= 0) return -1;
}
return buffer[ptr++];
}
int nextInt() throws IOException {
int c;
do {
c = read();
} while (c <= ' ' && c != -1);
int sign = 1;
if (c == '-') {
sign = -1;
c = read();
}
int val = 0;
while (c > ' ') {
val = val * 10 + (c - '0');
c = read();
}
return val * sign;
}
}
static final class SegTree {
int n;
int size;
int[] initMax; // initial relative maximums
int[] max; // current relative maximums
int[] lazy; // lazy add
void prepare(int n) {
if (this.n == n && initMax != null) return;
this.n = n;
this.size = 4 * n + 5;
if (initMax == null || initMax.length < size) {
initMax = new int[size];
max = new int[size];
lazy = new int[size];
}
buildInit(1, 1, n);
}
private void buildInit(int node, int l, int r) {
// Initial array is [0, 1, 2, ..., n-1]
// So maximum on segment [l, r] is r-1.
initMax[node] = r - 1;
if (l == r) return;
int mid = (l + r) >>> 1;
buildInit(node << 1, l, mid);
buildInit(node << 1 | 1, mid + 1, r);
}
void reset() {
System.arraycopy(initMax, 0, max, 0, size);
Arrays.fill(lazy, 0, size, 0);
}
int rootMax() {
return max[1];
}
private void apply(int node, int delta) {
max[node] += delta;
lazy[node] += delta;
}
private void push(int node) {
int add = lazy[node];
if (add != 0) {
apply(node << 1, add);
apply(node << 1 | 1, add);
lazy[node] = 0;
}
}
void addPrefix(int r) {
if (r <= 0) return;
addPrefix(1, 1, n, r);
}
private void addPrefix(int node, int l, int r, int limit) {
if (r <= limit) {
apply(node, 1);
return;
}
if (l == r) return;
push(node);
int mid = (l + r) >>> 1;
addPrefix(node << 1, l, mid, limit);
if (limit > mid) {
addPrefix(node << 1 | 1, mid + 1, r, limit);
}
max[node] = Math.max(max[node << 1], max[node << 1 | 1]);
}
int firstGE(int target) {
if (max[1] < target) return n + 1;
return firstGE(1, 1, n, target);
}
private int firstGE(int node, int l, int r, int target) {
if (l == r) return l;
push(node);
int mid = (l + r) >>> 1;
if (max[node << 1] >= target) {
return firstGE(node << 1, l, mid, target);
} else {
return firstGE(node << 1 | 1, mid + 1, r, target);
}
}
}
int n, k, m;
int[] a;
int[] leftMax;
final SegTree seg = new SegTree();
private boolean can(int p) {
final int n = this.n;
final int m = this.m;
final int[] a = this.a;
final int[] leftMax = this.leftMax;
// We work with h[j] = (j-1) + best_j.
// Initially: h[j] = j-1, so target for feasibility is m-1.
final int target = m - 1;
final int shift = p - m; // need = a[i] - shift = a[i] - p + m
// Left scan: for every position, compute the largest possible center rank.
seg.reset();
int border = m; // first j such that h[j] >= m-1
for (int i = 0; i < n; i++) {
leftMax[i] = m - border + 1;
int need = a[i] - shift;
if (need > 0) {
int r;
if (need > seg.rootMax()) {
r = m;
} else {
r = seg.firstGE(need) - 1;
}
if (r > 0) {
seg.addPrefix(r);
if (border > 1 && r >= border - 1) {
border = seg.firstGE(target);
}
}
}
}
// Right scan: for every position, compute the smallest possible center rank.
seg.reset();
border = m;
for (int i = n - 1; i >= 0; i--) {
int rightMin = border;
if (a[i] >= p && rightMin <= leftMax[i]) {
return true;
}
int need = a[i] - shift;
if (need > 0) {
int r;
if (need > seg.rootMax()) {
r = m;
} else {
r = seg.firstGE(need) - 1;
}
if (r > 0) {
seg.addPrefix(r);
if (border > 1 && r >= border - 1) {
border = seg.firstGE(target);
}
}
}
}
return false;
}
private void solve() throws Exception {
FastScanner fs = new FastScanner();
StringBuilder out = new StringBuilder();
int t = fs.nextInt();
while (t-- > 0) {
n = fs.nextInt();
k = fs.nextInt();
m = n - k;
if (a == null || a.length < n) a = new int[n];
if (leftMax == null || leftMax.length < n) leftMax = new int[n];
int maxA = 0;
for (int i = 0; i < n; i++) {
a[i] = fs.nextInt();
if (a[i] > maxA) maxA = a[i];
}
seg.prepare(m);
int lo = 1, hi = maxA, ans = 1;
while (lo <= hi) {
int mid = (lo + hi) >>> 1;
if (can(mid)) {
ans = mid;
lo = mid + 1;
} else {
hi = mid - 1;
}
}
out.append(ans).append('\n');
}
System.out.print(out.toString());
}
public static void main(String[] args) throws Exception {
new Main().solve();
}
}