#include <iostream>
#include <string>
#include <vector>

using namespace std;

class Order;

class Lift
{
	int currentFloor;
	vector<Order*> innerOrders;

	Lift(const Lift& v) {}
	Lift& operator = (const Lift& v) {}

public:
	Lift()
	{
		currentFloor = 1;
	}

	inline int getCurrentFloor() const
	{
		return currentFloor;
	}

	inline void changeCurrentFloor(int delta)
	{
		currentFloor += delta;
	}

	inline vector<Order*>& getInnerOrders()
	{
		return innerOrders;
	}
};

class Order
{
	int startTime;
	int endTime;
	int sourceFloor;
	bool upDirection;
	int targetFloor;
	int liftIndex;

	Order(const Order& v) {}
	Order& operator = (const Order& v) {}

public:
	Order(int time, int sourceFloor, bool upDirection): startTime(time), sourceFloor(sourceFloor), upDirection(upDirection)
	{
		targetFloor = -1;
		endTime = -1;
		liftIndex = -1;
	}

	inline int getStartTime() const
	{
		return startTime;
	}

	inline int getEndTime() const
	{
		return endTime;
	}
	inline void setEndTime(int endTime)
	{
		this->endTime = endTime;
	}

	inline int getSourceFloor() const
	{
		return sourceFloor;
	}

	inline bool isUpDirection() const
	{
		return upDirection;
	}

	inline int getTargetFloor() const
	{
		return targetFloor;
	}
	inline void setTargetFloor(int targetFloor)
	{
		this->targetFloor = targetFloor;
	}

	inline int getLiftIndex() const
	{
		return liftIndex;
	}
	inline void setLiftIndex(int liftIndex)
	{
		this->liftIndex = liftIndex;
	}
};

class GameState
{
	static const int MAX_WAIT_TIME = 360;

	int buildingHeight;
	int liftCount;
	vector<Order*> orders;
	vector<Lift*> lifts;

public:
	GameState(int buildingHeight, int liftCount): buildingHeight(buildingHeight), liftCount(liftCount) 
	{
		for (int i = 0; i < (int)liftCount; i++)
			lifts.push_back( new Lift() );
	}

	~GameState()
	{
		for (int i = 0; i < (int)orders.size(); i++)
			delete orders[i];
		for (int i = 0; i < (int)lifts.size(); i++)
			delete lifts[i];
	}

	inline int getBuildingHeight() const
	{
		return buildingHeight;
	}

	inline int getLiftCount() const
	{
		return liftCount;
	}
	
	Lift* getLift(int liftIndex) const
	{
		return lifts[liftIndex];
	}

	//Check order existance on specified floor
	bool existsOrder(int floor) const
	{
		for (int i = 0; i < (int)orders.size(); i++)
			if ( orders[i]->getSourceFloor() == floor && orders[i]->getLiftIndex() == -1 ) return true;
		return false;
	}

	bool existsUpOrder(int floor) const
	{
		for (int i = 0; i < (int)orders.size(); i++)
			if ( orders[i]->getSourceFloor() == floor && orders[i]->isUpDirection() && orders[i]->getLiftIndex() == -1) return true;
		return false;
	}

	void addNewOrder(int time, int floor, char direction)
	{
		orders.push_back( new Order(time, floor, direction=='u' || direction=='U') );
	}

	void removeElapsedOrders(int time)
	{
		for (int i = 0; i < (int)orders.size(); i++)
			if ( orders[i]->getLiftIndex() == -1 )
				if ( time - orders[i]->getStartTime() > MAX_WAIT_TIME )
				{
					delete orders[i];
					orders.erase(orders.begin() + i);
					i--;
				}
	}

	void boardPerson(int time, int liftIndex, int targetFloor)
	{
		bool isUp = (lifts[liftIndex]->getCurrentFloor() < targetFloor);
		for (int i = 0; i < (int)orders.size(); i++)
			if ( orders[i]->getLiftIndex() == -1 )
				if ( orders[i]->getSourceFloor() == lifts[liftIndex]->getCurrentFloor() )
					if ( orders[i]->isUpDirection() == isUp )
					{
						orders[i]->setLiftIndex(liftIndex);
						orders[i]->setTargetFloor(targetFloor);
						lifts[liftIndex]->getInnerOrders().push_back(orders[i]);
						break;
					}
	}

	void unboardPersons(int liftIndex)
	{
		for (int i = 0; i < (int)lifts[liftIndex]->getInnerOrders().size(); i++)
			if ( lifts[liftIndex]->getCurrentFloor() == lifts[liftIndex]->getInnerOrders()[i]->getTargetFloor() )
			{
				lifts[liftIndex]->getInnerOrders().erase( lifts[liftIndex]->getInnerOrders().begin() + i );
				i--;
			}
	}

	void readEvents()
	{
		int time;
		cin>>time;
		removeElapsedOrders(time);

		int orderFloor;
		cin>>orderFloor;
		char direction;
		if ( orderFloor != -1 )
		{
			cin>>direction;
			addNewOrder(time, orderFloor, direction);
		}

		int boardCount;
		cin>>boardCount;
		for (int i = 0; i < boardCount; i++)
		{
			int liftIndex;
			cin>>liftIndex;
			int personCount;
			cin>>personCount;
			for (int j = 0; j < personCount; j++)
			{
				int targetFloor;
				cin>>targetFloor;
				boardPerson(time, liftIndex, targetFloor);
			}
		}
	}

	void updateLiftState(const string& action)
	{
		for (int i = 0; i < (int)action.length(); i++)
		{
			if ( action[i]=='S' )
			{
				//nothing to do
			}
			else if ( action[i]=='U' )
			{
				lifts[i]->changeCurrentFloor(1);
			}
			else if ( action[i]=='D' )
			{
				lifts[i]->changeCurrentFloor(-1);
			}
			else if ( action[i]=='u' )
			{
				unboardPersons(i);
			}
			else if ( action[i]=='d' )
			{
				unboardPersons(i);
			}
		}
	}
};

class Bot
{
	const char* NAME;
	GameState* gameState;

public:
	Bot()
	{
		NAME = "SampleC++Bot";
	}

	~Bot()
	{
		delete gameState;
	}

	string getName() const
	{
		return NAME;
	}
	
	void setParams(int buildingHeight, int liftCount, int gameTime)
	{
		gameState = new GameState(buildingHeight, liftCount);
	}

	string getAction()
	{
		gameState->readEvents();

		string action;
		for (int i = 0; i < gameState->getLiftCount(); i++)
			action += getAction(i);

		gameState->updateLiftState(action);
		return action;
	}

	string getAction(int liftIndex)
	{
		int currentFloor = gameState->getLift(liftIndex)->getCurrentFloor();
		vector<Order*> innerOrders = gameState->getLift(liftIndex)->getInnerOrders();

		if ( innerOrders.size() > 0 )
		{
			bool wantUp = false;
			bool wantDown = false;
			bool wantExit = false;
			for (int i = 0; i < (int)innerOrders.size(); i++)
				if ( innerOrders[i]->getTargetFloor() == currentFloor ) 
					wantExit = true;
				else if ( innerOrders[i]->getTargetFloor() > currentFloor ) 
					wantUp = true;
				else 
					wantDown = true;

			if ( wantExit )
			{
				if ( wantUp ) return "u";
				if ( wantDown ) return "d";
				if ( currentFloor < gameState->getBuildingHeight() ) return "u";
				else return "d";
			}

			if ( wantUp ) return "U";
			else return "D"; 
		}
		else
		{
			int nearestOrderFloor = findNearestOrder(currentFloor);
			if ( nearestOrderFloor == -1 ) return "S";

			if ( nearestOrderFloor == currentFloor )
				if ( gameState->existsUpOrder(currentFloor) ) return "u";
				else return "d";

			if ( nearestOrderFloor > currentFloor ) return "U";
			else return "D";
		}
	}

	//Actually, it's not 'nearest' one :) Please implement nearest by yourself
	int findNearestOrder(int floor)
	{
		for (int i = floor; i >= 1; i--)
			if ( gameState->existsOrder(i) ) return i;

		for (int i = floor + 1; i <= gameState->getBuildingHeight(); i++)
			if ( gameState->existsOrder(i) ) return i;

		return -1;
	}

};

int main()
{
	Bot bot;
	while ( true )		
	{
		string command;
		cin>>command;
		
		if (command == "GetName")
		{
			cout<<bot.getName()<<"\n";
		}
		else if (command == "SetParams")
		{
			int buildingHeight;
			int liftCount;
			int gameTime;
			cin>>buildingHeight>>liftCount>>gameTime;
			bot.setParams(buildingHeight, liftCount, gameTime);
		}
		else if (command == "GetAction")
		{
			cout<<bot.getAction()<<"\n";
		}
		else
		{
			cout<<"Unknown command: "<<command<<"\n";
		}
	}

	return 0;
}
