#include<stdio.h>
#include<stdlib.h>
#include<math.h>

#define PI 3.14159265359

struct DOT {
	double x, y;
	struct DOT* next;
};

double Makedick(int XorY, double x1, double y1, double x2, double y2) {
	// NEW = A + 1/3 (B-A) + 1/3 * (B-A) * ROT(60)
	double newX = x1 + (x2 - x1) / 3 + cos(60 * PI / 180)*(x2 - x1) / 3 - sin(60 * PI / 180)*(y2 - y1) / 3;
	double newY = y1 + (y2 - y1) / 3 + sin(60 * PI / 180)*(x2 - x1) / 3 + cos(60 * PI / 180)*(y2 - y1) / 3;
	if (XorY == 0)return newX;
	else return newY;
}

struct DOT end = { 100,0,NULL };
struct DOT init = { 0,0,&end };

int MakeCurve(int n) {
	struct DOT* runP = &init;
	struct DOT* Add[3];
	int N, cnt;
	if (n == 0)return 1;
	N = MakeCurve(n - 1);
	cnt = N;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < 3; j++) {
			Add[j] = (struct DOT*)malloc(sizeof(struct DOT));
		}
		Add[0]->x = (runP->x * 2 + runP->next->x) / 3;
		Add[0]->y = (runP->y * 2 + runP->next->y) / 3;
		Add[1]->x = Makedick(0, runP->x, runP->y, runP->next->x, runP->next->y);
		Add[1]->y = Makedick(1, runP->x, runP->y, runP->next->x, runP->next->y);
		Add[2]->x = (runP->x + runP->next->x * 2)  / 3;
		Add[2]->y = (runP->y + runP->next->y * 2)  / 3;
		Add[2]->next = runP->next;
		Add[1]->next = Add[2];
		Add[0]->next = Add[1];
		runP->next = Add[0];
		runP = Add[2]->next;
		cnt += 3;
	}
	return cnt;
}

int main() {
	int n;
	struct DOT * pos;

	scanf("%d", &n);
	MakeCurve(n);
	for (pos = &init; pos != NULL; pos = pos->next) {
		printf("%lf %lf\n", pos->x, pos->y);
	}
	return 0;
}
