Just like with $\mathbf{NP}$, we have alternate characterizations of $\mathbf{NL}$ which give us a more intuitive understanding of what kinds of problems it encapsulates. Recall that we can think of $\mathbf{NP}$ as the problems with efficiently verifiable certificates. We have a similar characterization for $\mathbf{NL}$, with the additional restriction that the certificates can be read only once.
A language $A$ is in $\mathbf{NL}$ if there exists a verifier $M$ for $A$ that uses space $O(\log n)$ such that for every input string $w$, we have $w \in A$ if and only if $M$ accepts $\langle w,c \rangle$ for some string $c$ of length $n^k$ placed on a special read-once tape.
It turns out the restriction that the certificate is read-once is extremely important: if we allow the certificate to be read like a normal tape, the same machine will be able to decide problems in $\mathbf{NP}$.
Now, we'll make use of this alternative view of $\mathbf{NL}$ to consider problems in $\mathbf{coNL}$, which is defined as you'd expect. However, the following result will show that perhaps what we consider to be our intuitive understanding of computation and complexity is still rather incomplete.
Theorem. (Immerman-Szlepcsneyi) $\overline{\mathrm{PATH}} \in \mathbf{NL}$.
Proof. We need to show that there exists an $O(\log n)$ space algorithm such that there is a read-once polynomial certificate whenever a graph $G$ does not contain a path from $s$ to $t$.
First, we consider a more general problem. Let $C_i$ be the set of vertices that are reachable from $s$ in at most $i$ steps. For every $0 \leq i \leq n$ and vertex $v$, we can verify $v \in C_i$. The certificate contains the labels $v_0,v_1,\cdots,v_k$ of the vertices along the path from $s$ to $v$. An algorithm can check the certificate via read-once access by verifying:
To solve $\overline{\mathrm{PATH}}$, we describe an algorithm that makes use of procedures to solve the following subproblems:
We know that $C_0 = \{s\}$ and $C_n$ contains every vertex in $G$ that is reachable from $s$. Thus, we will use the second procedure to learn the size of $C_n$ and use the first to show that $t \not\in C_n$.
Now, we show that these procedures can be performed in logarithmic space.
First, to certify that $v$ is not in $C_i$ given $|C_i|$, the certificate just needs to list the certificates that each vertex $u \in C_i$, sorted in ascending order. The algorithm checks that:
This certificate will verify that $v \not\in C_i$. If $v \in C_i$, then there will not exist $|C_i|$ certificates showing that $u_1 < u_2 < \cdots < u_{|C_i|}$ are in $C_i$ and $u_j \neq v$ for every $j$.
Next, we show how to certify that $v \not\in C_i$ if we know $|C_{i-1}|$. This is the same as above except for the third step. We have a list of $|C_{i-1}|$ certificates for each $u \in C_{i-1}$. However, in the third step, we check that there is no certificate for $v$ or any of its neighbours. Why? Note that $v \in C_i$ if and only if there exists $u \in C_{i-1}$, where eiterh $u = v$ or $u$ is a neighbour of $v$.
Finally, to certify that $|C_i| = c$ given $|C_{i-1}|$, we note that if a vertex $v$ is in $C_{i-1}$, then there is a certificate to show this and that if $v \not\in C_{i-1}$, then there is a certificate for this too. The certificate that $|C_i| = c$ consists of $n$ certificates, one for each vertex in ascending order of labels. For each vertex $u$, there is a certificate depending on whether it is or is not in $C_i$. Then the algorithm verifies each certificate and counts the number of certificates that verify that a vertex is in $C_{i-1}$. $$\tag*{$\Box$}$$
Corollary. $\mathbf{NL} = \mathbf{coNL}$.