Por supuesto, si desea tomar su pregunta muy literalmente y evitar solo los saltos entre q1 y q2 (y, por ejemplo, permitir un salto entre q2 y q2), el problema se vuelve un poco más interesante:
\catcode`\@=11
\addtoparstylehooks{\xdef\lastmarker{\m@rker}}
\m@kedigitsletters
\def\@qone{q1}
\m@kedigitsother
\sethook{before}{q2}{\ifx\lastmarker\@qone\relax\nobreak\fi}
Aquí obtenemos el marcador del párrafo anterior al final de cada párrafo, y luego, antes de un q2, comprobamos si el marcador del último párrafo era un q1 y, de ser así, insertamos nobreak. Observe que, para comparar el marcador con q1, almacenamos q1 como algo con lo que comparar, pero el 1 en q1 es una letra y no un dígito, por lo que tenemos que reclasificar los dígitos como letras mientras hacemos ese def y luego devolverlos a su estado original. sethook es inteligente en que realiza la reclasificación por nosotros sin tener que hacer ese tipo de cosas.